给定一个未排序的整数数组,找到一个与给定数字相加的子数组。如果有多个子数组具有给定数字之和,则打印其中任何一个。
例子:
Input: arr[] = {1, 4, 20, 3, 10, 5}, sum = 33
Output: Sum found between indexes 2 and 4
Explanation: Sum of elements between indices
2 and 4 is 20 + 3 + 10 = 33
Input: arr[] = {10, 2, -2, -20, 10}, sum = -10
Output: Sum found between indexes 0 to 3
Explanation: Sum of elements between indices
0 and 3 is 10 + 2 - 2 - 20 = -10
Input: arr[] = {-10, 0, 2, -2, -20, 10}, sum = 20
Output: No subarray with given sum exists
Explanation: There is no subarray with the given sum
注意:我们在这里讨论了一个不处理负整数的解决方案。在这篇文章中,还处理了负整数。
方法:想法是将数组的每个前缀的元素总和存储在一个hashmap中,即每个索引存储直到该索引hashmap的元素总和。因此,要检查是否存在总和等于s的子数组,请检查每个索引 i,并将该索引汇总为x 。如果存在总和等于x – s的前缀,则找到具有给定总和的子数组。
算法:
- 创建一个 Hashmap ( hm ) 来存储一个键值对,即 key = prefix sum and value = 其索引,以及一个变量来存储当前和 ( sum = 0 ) 和子数组的总和为s
- 从头到尾遍历数组。
- 对于每个元素更新总和,即sum = sum + array[i]
- 如果总和等于 s,则打印具有给定总和的子数组是从 0 到 i
- 如果 HashMap 中存在任何等于sum – s 的键,则打印具有给定和的子数组是从 hm[sum – s] 到 i
- 将总和和索引作为键值对放入哈希图中。
上述方法的试运行:
执行:
C++
// C++ program to print subarray with sum as given sum
#include
using namespace std;
// Function to print subarray with sum as given sum
void subArraySum(int arr[], int n, int sum)
{
// create an empty map
unordered_map map;
// Maintains sum of elements so far
int curr_sum = 0;
for (int i = 0; i < n; i++)
{
// add current element to curr_sum
curr_sum = curr_sum + arr[i];
// if curr_sum is equal to target sum
// we found a subarray starting from index 0
// and ending at index i
if (curr_sum == sum)
{
cout << "Sum found between indexes "
<< 0 << " to " << i << endl;
return;
}
// If curr_sum - sum already exists in map
// we have found a subarray with target sum
if (map.find(curr_sum - sum) != map.end())
{
cout << "Sum found between indexes "
<< map[curr_sum - sum] + 1
<< " to " << i << endl;
return;
}
map[curr_sum] = i;
}
// If we reach here, then no subarray exists
cout << "No subarray with given sum exists";
}
// Driver program to test above function
int main()
{
int arr[] = {10, 2, -2, -20, 10};
int n = sizeof(arr)/sizeof(arr[0]);
int sum = -10;
subArraySum(arr, n, sum);
return 0;
}
Java
// Java program to print subarray with sum as given sum
import java.util.*;
class GFG {
public static void subArraySum(int[] arr, int n, int sum) {
//cur_sum to keep track of cummulative sum till that point
int cur_sum = 0;
int start = 0;
int end = -1;
HashMap hashMap = new HashMap<>();
for (int i = 0; i < n; i++) {
cur_sum = cur_sum + arr[i];
//check whether cur_sum - sum = 0, if 0 it means
//the sub array is starting from index 0- so stop
if (cur_sum - sum == 0) {
start = 0;
end = i;
break;
}
//if hashMap already has the value, means we already
// have subarray with the sum - so stop
if (hashMap.containsKey(cur_sum - sum)) {
start = hashMap.get(cur_sum - sum) + 1;
end = i;
break;
}
//if value is not present then add to hashmap
hashMap.put(cur_sum, i);
}
// if end is -1 : means we have reached end without the sum
if (end == -1) {
System.out.println("No subarray with given sum exists");
} else {
System.out.println("Sum found between indexes "
+ start + " to " + end);
}
}
// Driver code
public static void main(String[] args) {
int[] arr = {10, 2, -2, -20, 10};
int n = arr.length;
int sum = -10;
subArraySum(arr, n, sum);
}
}
Python3
# Python3 program to print subarray with sum as given sum
# Function to print subarray with sum as given sum
def subArraySum(arr, n, Sum):
# create an empty map
Map = {}
# Maintains sum of elements so far
curr_sum = 0
for i in range(0,n):
# add current element to curr_sum
curr_sum = curr_sum + arr[i]
# if curr_sum is equal to target sum
# we found a subarray starting from index 0
# and ending at index i
if curr_sum == Sum:
print("Sum found between indexes 0 to", i)
return
# If curr_sum - sum already exists in map
# we have found a subarray with target sum
if (curr_sum - Sum) in Map:
print("Sum found between indexes", \
Map[curr_sum - Sum] + 1, "to", i)
return
Map[curr_sum] = i
# If we reach here, then no subarray exists
print("No subarray with given sum exists")
# Driver program to test above function
if __name__ == "__main__":
arr = [10, 2, -2, -20, 10]
n = len(arr)
Sum = -10
subArraySum(arr, n, Sum)
# This code is contributed by Rituraj Jain
C#
using System;
using System.Collections.Generic;
// C# program to print subarray with sum as given sum
public class GFG
{
public static void subArraySum(int[] arr, int n, int sum)
{
//cur_sum to keep track of cummulative sum till that point
int cur_sum = 0;
int start = 0;
int end = -1;
Dictionary hashMap = new Dictionary();
for (int i = 0; i < n; i++)
{
cur_sum = cur_sum + arr[i];
//check whether cur_sum - sum = 0, if 0 it means
//the sub array is starting from index 0- so stop
if (cur_sum - sum == 0)
{
start = 0;
end = i;
break;
}
//if hashMap already has the value, means we already
// have subarray with the sum - so stop
if (hashMap.ContainsKey(cur_sum - sum))
{
start = hashMap[cur_sum - sum] + 1;
end = i;
break;
}
//if value is not present then add to hashmap
hashMap[cur_sum] = i;
}
// if end is -1 : means we have reached end without the sum
if (end == -1)
{
Console.WriteLine("No subarray with given sum exists");
}
else
{
Console.WriteLine("Sum found between indexes " + start + " to " + end);
}
}
// Driver code
public static void Main(string[] args)
{
int[] arr = new int[] {10, 2, -2, -20, 10};
int n = arr.Length;
int sum = -10;
subArraySum(arr, n, sum);
}
}
// This code is contributed by Shrikant13
Javascript
输出:
Sum found between indexes 0 to 3
复杂度分析:
- 时间复杂度: O(N)。
如果在数组的帮助下进行散列,那么这就是时间复杂度。如果元素不能在数组中散列,也可以使用散列映射,如上面的代码所示。 - 辅助空间: O(n)。
由于需要 HashMap,因此需要线性空间。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。