给定一个整数数组,找出总和等于 0 的最长子数组的长度。
例子:
Input: arr[] = {15, -2, 2, -8, 1, 7, 10, 23};
Output: 5
Explanation: The longest sub-array with
elements summing up-to 0 is {-2, 2, -8, 1, 7}
Input: arr[] = {1, 2, 3}
Output: 0
Explanation:There is no subarray with 0 sum
Input: arr[] = {1, 0, 3}
Output: 1
Explanation: The longest sub-array with
elements summing up-to 0 is {0}
朴素的方法:这涉及在使用两个嵌套循环的情况下使用蛮力。外循环用于固定子数组的起始位置,内循环用于子数组的结束位置,如果元素之和为零,则增加计数。
算法:
- 一一考虑所有子数组并检查每个子数组的总和。
- 运行两个循环:外循环选择起点 i,内循环尝试从 i 开始的所有子数组。
执行:
C++
/* A simple C++ program to find
largest subarray with 0 sum */
#include
using namespace std;
// Returns length of the largest
// subarray with 0 sum
int maxLen(int arr[], int n)
{
// Initialize result
int max_len = 0;
// Pick a starting point
for (int i = 0; i < n; i++) {
// Initialize currr_sum for
// every starting point
int curr_sum = 0;
// try all subarrays starting with 'i'
for (int j = i; j < n; j++) {
curr_sum += arr[j];
// If curr_sum becomes 0,
// then update max_len
// if required
if (curr_sum == 0)
max_len = max(max_len, j - i + 1);
}
}
return max_len;
}
// Driver Code
int main()
{
int arr[] = { 15, -2, 2, -8, 1, 7, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Length of the longest 0 sum subarray is "
<< maxLen(arr, n);
return 0;
}
Java
// Java code to find the largest subarray
// with 0 sum
class GFG {
// Returns length of the largest subarray
// with 0 sum
static int maxLen(int arr[], int n)
{
int max_len = 0;
// Pick a starting point
for (int i = 0; i < n; i++) {
// Initialize curr_sum for every
// starting point
int curr_sum = 0;
// try all subarrays starting with 'i'
for (int j = i; j < n; j++) {
curr_sum += arr[j];
// If curr_sum becomes 0, then update
// max_len
if (curr_sum == 0)
max_len = Math.max(max_len, j - i + 1);
}
}
return max_len;
}
public static void main(String args[])
{
int arr[] = { 15, -2, 2, -8, 1, 7, 10, 23 };
int n = arr.length;
System.out.println("Length of the longest 0 sum "
+ "subarray is " + maxLen(arr, n));
}
}
// This code is contributed by Kamal Rawal
Python
# Python program to find the length of largest subarray with 0 sum
# returns the length
def maxLen(arr):
# initialize result
max_len = 0
# pick a starting point
for i in range(len(arr)):
# initialize sum for every starting point
curr_sum = 0
# try all subarrays starting with 'i'
for j in range(i, len(arr)):
curr_sum += arr[j]
# if curr_sum becomes 0, then update max_len
if curr_sum == 0:
max_len = max(max_len, j-i + 1)
return max_len
# test array
arr = [15, -2, 2, -8, 1, 7, 10, 13]
print "Length of the longest 0 sum subarray is % d" % maxLen(arr)
C#
// C# code to find the largest
// subarray with 0 sum
using System;
class GFG {
// Returns length of the
// largest subarray with 0 sum
static int maxLen(int[] arr, int n)
{
int max_len = 0;
// Pick a starting point
for (int i = 0; i < n; i++) {
// Initialize curr_sum
// for every starting point
int curr_sum = 0;
// try all subarrays
// starting with 'i'
for (int j = i; j < n; j++) {
curr_sum += arr[j];
// If curr_sum becomes 0,
// then update max_len
if (curr_sum == 0)
max_len = Math.Max(max_len,
j - i + 1);
}
}
return max_len;
}
// Driver code
static public void Main()
{
int[] arr = { 15, -2, 2, -8,
1, 7, 10, 23 };
int n = arr.Length;
Console.WriteLine("Length of the longest 0 sum "
+ "subarray is " + maxLen(arr, n));
}
}
// This code is contributed by ajit
PHP
Javascript
C++
// C++ program to find the length of largest subarray
// with 0 sum
#include
using namespace std;
// Returns Length of the required subarray
int maxLen(int arr[], int n)
{
// Map to store the previous sums
unordered_map presum;
int sum = 0; // Initialize the sum of elements
int max_len = 0; // Initialize result
// Traverse through the given array
for (int i = 0; i < n; i++) {
// Add current element to sum
sum += arr[i];
if (arr[i] == 0 && max_len == 0)
max_len = 1;
if (sum == 0)
max_len = i + 1;
// Look for this sum in Hash table
if (presum.find(sum) != presum.end()) {
// If this sum is seen before, then update max_len
max_len = max(max_len, i - presum[sum]);
}
else {
// Else insert this sum with index in hash table
presum[sum] = i;
}
}
return max_len;
}
// Driver Code
int main()
{
int arr[] = { 15, -2, 2, -8, 1, 7, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Length of the longest 0 sum subarray is "
<< maxLen(arr, n);
return 0;
}
Java
// A Java program to find maximum length subarray with 0 sum
import java.util.HashMap;
class MaxLenZeroSumSub {
// Returns length of the maximum length subarray with 0 sum
static int maxLen(int arr[])
{
// Creates an empty hashMap hM
HashMap hM = new HashMap();
int sum = 0; // Initialize sum of elements
int max_len = 0; // Initialize result
// Traverse through the given array
for (int i = 0; i < arr.length; i++) {
// Add current element to sum
sum += arr[i];
if (arr[i] == 0 && max_len == 0)
max_len = 1;
if (sum == 0)
max_len = i + 1;
// Look this sum in hash table
Integer prev_i = hM.get(sum);
// If this sum is seen before, then update max_len
// if required
if (prev_i != null)
max_len = Math.max(max_len, i - prev_i);
else // Else put this sum in hash table
hM.put(sum, i);
}
return max_len;
}
// Drive method
public static void main(String arg[])
{
int arr[] = { 15, -2, 2, -8, 1, 7, 10, 23 };
System.out.println("Length of the longest 0 sum subarray is "
+ maxLen(arr));
}
}
Python
# A python program to find maximum length subarray
# with 0 sum in o(n) time
# Returns the maximum length
def maxLen(arr):
# NOTE: Dictonary in python in implemented as Hash Maps
# Create an empty hash map (dictionary)
hash_map = {}
# Initialize result
max_len = 0
# Initialize sum of elements
curr_sum = 0
# Traverse through the given array
for i in range(len(arr)):
# Add the current element to the sum
curr_sum += arr[i]
if arr[i] is 0 and max_len is 0:
max_len = 1
if curr_sum is 0:
max_len = i + 1
# NOTE: 'in' operation in dictionary to search
# key takes O(1). Look if current sum is seen
# before
if curr_sum in hash_map:
max_len = max(max_len, i - hash_map[curr_sum] )
else:
# else put this sum in dictionary
hash_map[curr_sum] = i
return max_len
# test array
arr = [15, -2, 2, -8, 1, 7, 10, 13]
print "Length of the longest 0 sum subarray is % d" % maxLen(arr)
C#
// C# program to find maximum
// length subarray with 0 sum
using System;
using System.Collections.Generic;
public class MaxLenZeroSumSub {
// Returns length of the maximum
// length subarray with 0 sum
static int maxLen(int[] arr)
{
// Creates an empty hashMap hM
Dictionary hM = new Dictionary();
int sum = 0; // Initialize sum of elements
int max_len = 0; // Initialize result
// Traverse through the given array
for (int i = 0; i < arr.GetLength(0); i++) {
// Add current element to sum
sum += arr[i];
if (arr[i] == 0 && max_len == 0)
max_len = 1;
if (sum == 0)
max_len = i + 1;
// Look this sum in hash table
int prev_i = 0;
if (hM.ContainsKey(sum)) {
prev_i = hM[sum];
}
// If this sum is seen before, then update max_len
// if required
if (hM.ContainsKey(sum))
max_len = Math.Max(max_len, i - prev_i);
else {
// Else put this sum in hash table
if (hM.ContainsKey(sum))
hM.Remove(sum);
hM.Add(sum, i);
}
}
return max_len;
}
// Driver code
public static void Main()
{
int[] arr = { 15, -2, 2, -8, 1, 7, 10, 23 };
Console.WriteLine("Length of the longest 0 sum subarray is "
+ maxLen(arr));
}
}
/* This code contributed by PrinciRaj1992 */
Javascript
输出:
Length of the longest 0 sum subarray is 5
复杂度分析:
- 时间复杂度:O(n^2) 由于使用了嵌套循环。
- 空间复杂度:O(1),因为没有使用额外的空间。
有效方法:蛮力解决方案是计算每个子阵列的总和并检查总和是否为零。现在让我们尝试通过占用 ‘n’ 长度的额外空间来提高时间复杂度。新数组将存储直到该索引的所有元素的总和。 sum-index 对将存储在hash-map 中。哈希映射允许在恒定时间内插入和删除键值对。因此,时间复杂度不受影响。因此,如果相同的值在数组中出现两次,则可以保证特定数组将是零和子数组。
数学证明:
prefix(i) = arr[0] + arr[1] +…+ arr[i]
prefix(j) = arr[0] + arr[1] +…+ arr[j], j>i
ifprefix(i) == prefix(j) then prefix(j) – prefix(i) = 0 that means arr[i+1] + .. + arr[j] = 0, So a sub-array has zero sum , and the length of that sub-array is j-i+1
算法:
- 创建一个额外的空间、一个长度为 n (prefix)的数组、一个变量 (sum) 、长度 (max_len)和一个哈希映射 (hm)以将 sum-index 对存储为键值对。
- 沿着输入数组从开始到结束移动。
- 对于每个索引,更新sum = sum + array[i] 的值。
- 检查每个索引,如果当前和是否存在于哈希映射中。
- 如果存在,将max_len的值更新为两个索引(当前索引和哈希映射中的索引)和max_len 的最大差值。
- 否则,将值(和)放入哈希映射中,索引作为键值对。
- 打印最大长度(max_len)。
以下是上述方法的试运行:
执行:
C++
// C++ program to find the length of largest subarray
// with 0 sum
#include
using namespace std;
// Returns Length of the required subarray
int maxLen(int arr[], int n)
{
// Map to store the previous sums
unordered_map presum;
int sum = 0; // Initialize the sum of elements
int max_len = 0; // Initialize result
// Traverse through the given array
for (int i = 0; i < n; i++) {
// Add current element to sum
sum += arr[i];
if (arr[i] == 0 && max_len == 0)
max_len = 1;
if (sum == 0)
max_len = i + 1;
// Look for this sum in Hash table
if (presum.find(sum) != presum.end()) {
// If this sum is seen before, then update max_len
max_len = max(max_len, i - presum[sum]);
}
else {
// Else insert this sum with index in hash table
presum[sum] = i;
}
}
return max_len;
}
// Driver Code
int main()
{
int arr[] = { 15, -2, 2, -8, 1, 7, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Length of the longest 0 sum subarray is "
<< maxLen(arr, n);
return 0;
}
Java
// A Java program to find maximum length subarray with 0 sum
import java.util.HashMap;
class MaxLenZeroSumSub {
// Returns length of the maximum length subarray with 0 sum
static int maxLen(int arr[])
{
// Creates an empty hashMap hM
HashMap hM = new HashMap();
int sum = 0; // Initialize sum of elements
int max_len = 0; // Initialize result
// Traverse through the given array
for (int i = 0; i < arr.length; i++) {
// Add current element to sum
sum += arr[i];
if (arr[i] == 0 && max_len == 0)
max_len = 1;
if (sum == 0)
max_len = i + 1;
// Look this sum in hash table
Integer prev_i = hM.get(sum);
// If this sum is seen before, then update max_len
// if required
if (prev_i != null)
max_len = Math.max(max_len, i - prev_i);
else // Else put this sum in hash table
hM.put(sum, i);
}
return max_len;
}
// Drive method
public static void main(String arg[])
{
int arr[] = { 15, -2, 2, -8, 1, 7, 10, 23 };
System.out.println("Length of the longest 0 sum subarray is "
+ maxLen(arr));
}
}
Python
# A python program to find maximum length subarray
# with 0 sum in o(n) time
# Returns the maximum length
def maxLen(arr):
# NOTE: Dictonary in python in implemented as Hash Maps
# Create an empty hash map (dictionary)
hash_map = {}
# Initialize result
max_len = 0
# Initialize sum of elements
curr_sum = 0
# Traverse through the given array
for i in range(len(arr)):
# Add the current element to the sum
curr_sum += arr[i]
if arr[i] is 0 and max_len is 0:
max_len = 1
if curr_sum is 0:
max_len = i + 1
# NOTE: 'in' operation in dictionary to search
# key takes O(1). Look if current sum is seen
# before
if curr_sum in hash_map:
max_len = max(max_len, i - hash_map[curr_sum] )
else:
# else put this sum in dictionary
hash_map[curr_sum] = i
return max_len
# test array
arr = [15, -2, 2, -8, 1, 7, 10, 13]
print "Length of the longest 0 sum subarray is % d" % maxLen(arr)
C#
// C# program to find maximum
// length subarray with 0 sum
using System;
using System.Collections.Generic;
public class MaxLenZeroSumSub {
// Returns length of the maximum
// length subarray with 0 sum
static int maxLen(int[] arr)
{
// Creates an empty hashMap hM
Dictionary hM = new Dictionary();
int sum = 0; // Initialize sum of elements
int max_len = 0; // Initialize result
// Traverse through the given array
for (int i = 0; i < arr.GetLength(0); i++) {
// Add current element to sum
sum += arr[i];
if (arr[i] == 0 && max_len == 0)
max_len = 1;
if (sum == 0)
max_len = i + 1;
// Look this sum in hash table
int prev_i = 0;
if (hM.ContainsKey(sum)) {
prev_i = hM[sum];
}
// If this sum is seen before, then update max_len
// if required
if (hM.ContainsKey(sum))
max_len = Math.Max(max_len, i - prev_i);
else {
// Else put this sum in hash table
if (hM.ContainsKey(sum))
hM.Remove(sum);
hM.Add(sum, i);
}
}
return max_len;
}
// Driver code
public static void Main()
{
int[] arr = { 15, -2, 2, -8, 1, 7, 10, 23 };
Console.WriteLine("Length of the longest 0 sum subarray is "
+ maxLen(arr));
}
}
/* This code contributed by PrinciRaj1992 */
Javascript
输出:
Length of the longest 0 sum subarray is 5
复杂度分析:
- 时间复杂度: O(n),由于使用了良好的散列函数,将允许在 O(1) 时间内进行插入和检索操作。
- 空间复杂度: O(n),用于使用额外空间来存储前缀数组和哈希图。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。