给定正负数数组,任务是找出总和最接近0的子数组。
可以有多个这样的子数组,我们只需要输出其中之一即可。
例子:
Input : arr[] = {-1, 3, 2, -5, 4}
Output : 1, 3
Subarray from index 1 to 3 has sum closest to 0 i.e.
3 + 2 + -5 = 0
Input : {2, -5, 4, -6, 3}
Output : 0, 2
2 + -5 + 4 = 1 closest to 0
提问人:微软
幼稚的方法是一一考虑所有子阵列,并更新总和最接近0的子阵列索引。
C++
// C++ program to find subarray with
// sum closest to 0
#include
using namespace std;
// Function to find the subarray
pair findSubArray(int arr[], int n)
{
int start, end, min_sum = INT_MAX;
// Pick a starting point
for (int i = 0; i < n; i++) {
// Consider current starting point
// as a subarray and update minimum
// sum and subarray indexes
int curr_sum = arr[i];
if (min_sum > abs(curr_sum)) {
min_sum = abs(curr_sum);
start = i;
end = i;
}
// Try all subarrays starting with i
for (int j = i + 1; j < n; j++) {
curr_sum = curr_sum + arr[j];
// update minimum sum
// and subarray indexes
if (min_sum > abs(curr_sum)) {
min_sum = abs(curr_sum);
start = i;
end = j;
}
}
}
// Return starting and ending indexes
pair p = make_pair(start, end);
return p;
}
// Drivers code
int main()
{
int arr[] = { 2, -5, 4, -6, -3 };
int n = sizeof(arr) / sizeof(arr[0]);
pair point = findSubArray(arr, n);
cout << "Subarray starting from ";
cout << point.first << " to " << point.second;
return 0;
}
Java
// Java program to find subarray with
// sum closest to 0
class GFG
{
static class Pair
{
int first, second;
public Pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Function to find the subarray
static Pair findSubArray(int arr[], int n)
{
int start = 0, end = 0, min_sum = Integer.MAX_VALUE;
// Pick a starting point
for (int i = 0; i < n; i++)
{
// Consider current starting point
// as a subarray and update minimum
// sum and subarray indexes
int curr_sum = arr[i];
if (min_sum > Math.abs(curr_sum))
{
min_sum = Math.abs(curr_sum);
start = i;
end = i;
}
// Try all subarrays starting with i
for (int j = i + 1; j < n; j++)
{
curr_sum = curr_sum + arr[j];
// update minimum sum
// and subarray indexes
if (min_sum > Math.abs(curr_sum))
{
min_sum = Math.abs(curr_sum);
start = i;
end = j;
}
}
}
// Return starting and ending indexes
Pair p = new Pair(start, end);
return p;
}
// Drivers code
public static void main(String[] args)
{
int arr[] = {2, -5, 4, -6, -3};
int n = arr.length;
Pair point = findSubArray(arr, n);
System.out.println("Subarray starting from "
+ point.first + " to " + point.second);
}
}
// This code has been contributed by 29AjayKumar
Python3
# Python 3 program to find subarray with
# sum closest to 0
import sys
# Function to find the subarray
def findSubArray(arr, n):
min_sum = sys.maxsize
# Pick a starting point
for i in range(n):
# Consider current starting point
# as a subarray and update minimum
# sum and subarray indexes
curr_sum = arr[i]
if (min_sum > abs(curr_sum)):
min_sum = abs(curr_sum)
start = i
end = i
# Try all subarrays starting with i
for j in range(i + 1, n, 1):
curr_sum = curr_sum + arr[j]
# update minimum sum
# and subarray indexes
if (min_sum > abs(curr_sum)):
min_sum = abs(curr_sum)
start = i
end = j
# Return starting and ending indexes
p = [start, end]
return p
# Driver Code
if __name__ == '__main__':
arr = [2, -5, 4, -6, -3]
n = len(arr)
point = findSubArray(arr, n)
print("Subarray starting from ", end = "")
print(point[0], "to", point[1])
# This code is contributed by
# Surendra_Gangwar
C#
// C# program to find subarray with
// sum closest to 0
using System;
class GFG
{
public class Pair
{
public int first, second;
public Pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Function to find the subarray
static Pair findSubArray(int []arr, int n)
{
int start = 0, end = 0, min_sum = int.MaxValue;
// Pick a starting point
for (int i = 0; i < n; i++)
{
// Consider current starting point
// as a subarray and update minimum
// sum and subarray indexes
int curr_sum = arr[i];
if (min_sum > Math.Abs(curr_sum))
{
min_sum = Math.Abs(curr_sum);
start = i;
end = i;
}
// Try all subarrays starting with i
for (int j = i + 1; j < n; j++)
{
curr_sum = curr_sum + arr[j];
// update minimum sum
// and subarray indexes
if (min_sum > Math.Abs(curr_sum))
{
min_sum = Math.Abs(curr_sum);
start = i;
end = j;
}
}
}
// Return starting and ending indexes
Pair p = new Pair(start, end);
return p;
}
// Drivers code
public static void Main(String[] args)
{
int []arr = {2, -5, 4, -6, -3};
int n = arr.Length;
Pair point = findSubArray(arr, n);
Console.WriteLine("Subarray starting from "
+ point.first + " to " + point.second);
}
}
// This code is contributed by Princi Singh
C++
// C++ program to find subarray with sum
// closest to 0
#include
using namespace std;
struct prefix {
int sum;
int index;
};
// Sort on the basis of sum
bool comparison(prefix a, prefix b)
{
return a.sum < b.sum;
}
// Returns subarray with sum closest to 0.
pair findSubArray(int arr[], int n)
{
int start, end, min_diff = INT_MAX;
prefix pre_sum[n + 1];
// To consider the case of subarray starting
// from beginning of the array
pre_sum[0].sum = 0;
pre_sum[0].index = -1;
// Store prefix sum with index
for (int i = 1; i <= n; i++) {
pre_sum[i].sum = pre_sum[i-1].sum + arr[i-1];
pre_sum[i].index = i - 1;
}
// Sort on the basis of sum
sort(pre_sum, pre_sum + (n + 1), comparison);
// Find two consecutive elements with minimum difference
for (int i = 1; i <= n; i++) {
int diff = pre_sum[i].sum - pre_sum[i-1].sum;
// Update minimum difference
// and starting and ending indexes
if (min_diff > diff) {
min_diff = diff;
start = pre_sum[i-1].index;
end = pre_sum[i].index;
}
}
// Return starting and ending indexes
pair p = make_pair(start + 1, end);
return p;
}
// Drivers code
int main()
{
int arr[] = { 2, 3, -4, -1, 6 };
int n = sizeof(arr) / sizeof(arr[0]);
pair point = findSubArray(arr, n);
cout << "Subarray starting from ";
cout << point.first << " to " << point.second;
return 0;
}
Java
// Java program to find subarray with sum
// closest to 0
import java.util.*;
class Prefix
{
int sum, index;
}
class Pair
{
int first, second;
Pair(int a, int b)
{
first = a;
second = b;
}
}
class GFG{
// Returns subarray with sum closest to 0.
static Pair findSubArray(int arr[], int n)
{
int start = -1, end = -1,
min_diff = Integer.MAX_VALUE;
Prefix pre_sum[] = new Prefix[n + 1];
for(int i = 0; i < n + 1; i++)
pre_sum[i] = new Prefix();
// To consider the case of subarray starting
// from beginning of the array
pre_sum[0].sum = 0;
pre_sum[0].index = -1;
// Store prefix sum with index
for(int i = 1; i <= n; i++)
{
pre_sum[i].sum = pre_sum[i - 1].sum +
arr[i - 1];
pre_sum[i].index = i - 1;
}
// Sort on the basis of sum
Arrays.sort(pre_sum, ((a, b) -> a.sum - b.sum));
// Find two consecutive elements with minimum
// difference
for(int i = 1; i <= n; i++)
{
int diff = pre_sum[i].sum -
pre_sum[i - 1].sum;
// Update minimum difference
// and starting and ending indexes
if (min_diff > diff)
{
min_diff = diff;
start = pre_sum[i - 1].index;
end = pre_sum[i].index;
}
}
// Return starting and ending indexes
Pair p = new Pair(start + 1, end);
return p;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 2, 3, -4, -1, 6 };
int n = arr.length;
Pair point = findSubArray(arr, n);
System.out.print("Subarray starting from ");
System.out.println(point.first + " to " +
point.second);
}
}
// This code is contributed by jrishabh99
Python3
# Python3 program to find subarray
# with sum closest to 0
class prefix:
def __init__(self, sum, index):
self.sum = sum
self.index = index
# Returns subarray with sum closest to 0.
def findSubArray(arr, n):
start, end, min_diff = None, None, float('inf')
pre_sum = [None] * (n + 1)
# To consider the case of subarray
# starting from beginning of the array
pre_sum[0] = prefix(0, -1)
# Store prefix sum with index
for i in range(1, n + 1):
pre_sum[i] = prefix(pre_sum[i - 1].sum +
arr[i - 1], i - 1)
# Sort on the basis of sum
pre_sum.sort(key = lambda x: x.sum)
# Find two consecutive elements
# with minimum difference
for i in range(1, n + 1):
diff = pre_sum[i].sum - pre_sum[i - 1].sum
# Update minimum difference
# and starting and ending indexes
if min_diff > diff:
min_diff = diff
start = pre_sum[i - 1].index
end = pre_sum[i].index
# Return starting and ending indexes
return (start + 1, end)
# Driver code
if __name__ == "__main__":
arr = [2, 3, -4, -1, 6]
n = len(arr)
point = findSubArray(arr, n)
print("Subarray starting from",
point[0], "to", point[1])
# This code is contributed by Rituraj Jain
输出:
Subarray starting from 0 to 2
时间复杂度: O(n 2 )
一种有效的方法是执行以下步骤:
- 维护一个前缀求和数组。还要在前缀和数组中维护索引。
- 根据总和对前缀总和数组进行排序。
- 在前缀和数组中找到具有最小差异的两个元素。
i.e. Find min(pre_sum[i] - pre_sum[i-1])
- 返回具有最小差异的pre_sum索引。
- 具有(lower_index + 1,upper_index)的子数组的总和最接近0。
- 采用lower_index + 1,因为在lower_index上减去值后,我们得到的总和最接近0。这就是为什么不必包含lower_index的原因。
C++
// C++ program to find subarray with sum
// closest to 0
#include
using namespace std;
struct prefix {
int sum;
int index;
};
// Sort on the basis of sum
bool comparison(prefix a, prefix b)
{
return a.sum < b.sum;
}
// Returns subarray with sum closest to 0.
pair findSubArray(int arr[], int n)
{
int start, end, min_diff = INT_MAX;
prefix pre_sum[n + 1];
// To consider the case of subarray starting
// from beginning of the array
pre_sum[0].sum = 0;
pre_sum[0].index = -1;
// Store prefix sum with index
for (int i = 1; i <= n; i++) {
pre_sum[i].sum = pre_sum[i-1].sum + arr[i-1];
pre_sum[i].index = i - 1;
}
// Sort on the basis of sum
sort(pre_sum, pre_sum + (n + 1), comparison);
// Find two consecutive elements with minimum difference
for (int i = 1; i <= n; i++) {
int diff = pre_sum[i].sum - pre_sum[i-1].sum;
// Update minimum difference
// and starting and ending indexes
if (min_diff > diff) {
min_diff = diff;
start = pre_sum[i-1].index;
end = pre_sum[i].index;
}
}
// Return starting and ending indexes
pair p = make_pair(start + 1, end);
return p;
}
// Drivers code
int main()
{
int arr[] = { 2, 3, -4, -1, 6 };
int n = sizeof(arr) / sizeof(arr[0]);
pair point = findSubArray(arr, n);
cout << "Subarray starting from ";
cout << point.first << " to " << point.second;
return 0;
}
Java
// Java program to find subarray with sum
// closest to 0
import java.util.*;
class Prefix
{
int sum, index;
}
class Pair
{
int first, second;
Pair(int a, int b)
{
first = a;
second = b;
}
}
class GFG{
// Returns subarray with sum closest to 0.
static Pair findSubArray(int arr[], int n)
{
int start = -1, end = -1,
min_diff = Integer.MAX_VALUE;
Prefix pre_sum[] = new Prefix[n + 1];
for(int i = 0; i < n + 1; i++)
pre_sum[i] = new Prefix();
// To consider the case of subarray starting
// from beginning of the array
pre_sum[0].sum = 0;
pre_sum[0].index = -1;
// Store prefix sum with index
for(int i = 1; i <= n; i++)
{
pre_sum[i].sum = pre_sum[i - 1].sum +
arr[i - 1];
pre_sum[i].index = i - 1;
}
// Sort on the basis of sum
Arrays.sort(pre_sum, ((a, b) -> a.sum - b.sum));
// Find two consecutive elements with minimum
// difference
for(int i = 1; i <= n; i++)
{
int diff = pre_sum[i].sum -
pre_sum[i - 1].sum;
// Update minimum difference
// and starting and ending indexes
if (min_diff > diff)
{
min_diff = diff;
start = pre_sum[i - 1].index;
end = pre_sum[i].index;
}
}
// Return starting and ending indexes
Pair p = new Pair(start + 1, end);
return p;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 2, 3, -4, -1, 6 };
int n = arr.length;
Pair point = findSubArray(arr, n);
System.out.print("Subarray starting from ");
System.out.println(point.first + " to " +
point.second);
}
}
// This code is contributed by jrishabh99
Python3
# Python3 program to find subarray
# with sum closest to 0
class prefix:
def __init__(self, sum, index):
self.sum = sum
self.index = index
# Returns subarray with sum closest to 0.
def findSubArray(arr, n):
start, end, min_diff = None, None, float('inf')
pre_sum = [None] * (n + 1)
# To consider the case of subarray
# starting from beginning of the array
pre_sum[0] = prefix(0, -1)
# Store prefix sum with index
for i in range(1, n + 1):
pre_sum[i] = prefix(pre_sum[i - 1].sum +
arr[i - 1], i - 1)
# Sort on the basis of sum
pre_sum.sort(key = lambda x: x.sum)
# Find two consecutive elements
# with minimum difference
for i in range(1, n + 1):
diff = pre_sum[i].sum - pre_sum[i - 1].sum
# Update minimum difference
# and starting and ending indexes
if min_diff > diff:
min_diff = diff
start = pre_sum[i - 1].index
end = pre_sum[i].index
# Return starting and ending indexes
return (start + 1, end)
# Driver code
if __name__ == "__main__":
arr = [2, 3, -4, -1, 6]
n = len(arr)
point = findSubArray(arr, n)
print("Subarray starting from",
point[0], "to", point[1])
# This code is contributed by Rituraj Jain
输出:
Subarray starting from 0 to 3
时间复杂度: O(n log n)
参考:
https://www.careercup.com/question?id=14583859