📌  相关文章
📜  查找给定总和的子数组 |设置 2(处理负数)

📅  最后修改于: 2021-10-27 07:39:55             🧑  作者: Mango

给定一个未排序的整数数组,找到一个与给定数字相加的子数组。如果有多个子数组具有给定数字之和,则打印其中任何一个。

例子:

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的前缀,则找到具有给定总和的子数组。

算法:

  1. 创建一个 Hashmap ( hm ) 来存储一个键值对,即 key = prefix sum and value = 其索引,以及一个变量来存储当前和 ( sum = 0 ) 和子数组的总和为s
  2. 从头到尾遍历数组。
  3. 对于每个元素更新总和,即sum = sum + array[i]
  4. 如果总和等于 s,则打印具有给定总和的子数组是从 0 到 i
  5. 如果 HashMap 中存在任何等于sum – s 的键,则打印具有给定和的子数组是从 hm[sum – s] 到 i
  6. 将总和和索引作为键值对放入哈希图中。

上述方法的试运行:

执行:

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 现场工作专业课程学生竞争性编程现场课程