📌  相关文章
📜  总和恰好等于 k 的子数组的数量

📅  最后修改于: 2021-10-27 06:56:48             🧑  作者: Mango

给定一个未排序的整数数组,找出总和恰好等于给定数字 k 的子数组的数量。

例子:

Input : arr[] = {10, 2, -2, -20, 10}, 
        k = -10
Output : 3
Subarrays: arr[0...3], arr[1...4], arr[3..4]
have sum exactly equal to -10.

Input : arr[] = {9, 4, 20, 3, 10, 5},
            k = 33
Output : 2
Subarrays : arr[0...2], arr[2...4] have sum
exactly equal to 33.

天真的解决方案 –
一个简单的解决方案是遍历所有子数组并计算它们的总和。如果总和等于所需的总和,则增加子数组的计数。打印子数组的最终计数。以下是幼稚的实现——

C++
// C++ program for
// the above approach
#include 
using namespace std;
int main()
{
  int arr[] = {10, 2, -2, -20, 10};
  int k = -10;
  int n = sizeof(arr) / sizeof(arr[0]);
  int res = 0;
 
  // Calculate all subarrays
  for (int i = 0; i < n; i++)
  {
    int sum = 0;
    for (int j = i; j < n; j++)
    {
      // Calculate required sum
      sum += arr[j];
 
      // Check if sum is equal to
      // required sum
      if (sum == k)
        res++;
    }
  }
  cout << (res) << endl;
}
 
// This code is contributed by Chitranayal


Java
// Java program for
// the above approach
import java.util.*;
class Solution {
     
    public static void main(String[] args)
    {
        int arr[] = { 10, 2, -2, -20, 10 };
        int k = -10;
        int n = arr.length;
        int res = 0;
         
        // calculate all subarrays
        for (int i = 0; i < n; i++) {
             
            int sum = 0;
            for (int j = i; j < n; j++) {
                 
                // calculate required sum
                sum += arr[j];
                 
                // check if sum is equal to
                // required sum
                if (sum == k)
                    res++;
            }
        }
        System.out.println(res);
    }
}


Python3
# Python3 program for
# the above approach
arr = [ 10, 2, -2, -20, 10 ]
n = len(arr)
k = -10
res = 0
 
# Calculate all subarrays
for i in range(n):
    summ = 0           
    for j in range(i, n):
         
        # Calculate required sum
        summ += arr[j]
 
        # Check if sum is equal to
        # required sum
        if summ == k:
            res += 1
 
print(res)
 
# This code is contributed by kavan155gondalia


C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG {
     
  static void Main() {
      int[] arr = {10, 2, -2, -20, 10};
      int k = -10;
      int n = arr.Length;
      int res = 0;
      
      // Calculate all subarrays
      for (int i = 0; i < n; i++)
      {
        int sum = 0;
        for (int j = i; j < n; j++)
        {
           
          // Calculate required sum
          sum += arr[j];
      
          // Check if sum is equal to
          // required sum
          if (sum == k)
            res++;
        }
      }
      Console.WriteLine(res);
  }
}
 
// This code is contributed by divyesh072019


Javascript


C++
// C++ program to find number of subarrays
// with sum exactly equal to k.
#include 
using namespace std;
 
// Function to find number of subarrays
// with sum exactly equal to k.
int findSubarraySum(int arr[], int n, int sum)
{
    // STL map to store number of subarrays
    // starting from index zero having
    // particular value of sum.
    unordered_map prevSum;
 
    int res = 0;
 
    // Sum of elements so far.
    int currsum = 0;
 
    for (int i = 0; i < n; i++) {
 
        // Add current element to sum so far.
        currsum += arr[i];
 
        // If currsum is equal to desired sum,
        // then a new subarray is found. So
        // increase count of subarrays.
        if (currsum == sum)
            res++;
 
        // currsum exceeds given sum by currsum
        //  - sum. Find number of subarrays having
        // this sum and exclude those subarrays
        // from currsum by increasing count by
        // same amount.
        if (prevSum.find(currsum - sum) != prevSum.end())
            res += (prevSum[currsum - sum]);
 
        // Add currsum value to count of
        // different values of sum.
        prevSum[currsum]++;
    }
 
    return res;
}
 
int main()
{
    int arr[] = { 10, 2, -2, -20, 10 };
    int sum = -10;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << findSubarraySum(arr, n, sum);
    return 0;
}


Java
// Java program to find number of subarrays
// with sum exactly equal to k.
import java.util.HashMap;
import java.util.Map;
 
public class GfG {
 
    // Function to find number of subarrays
    // with sum exactly equal to k.
    static int findSubarraySum(int arr[], int n, int sum)
    {
        // HashMap to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        HashMap prevSum = new HashMap<>();
 
        int res = 0;
 
        // Sum of elements so far.
        int currsum = 0;
 
        for (int i = 0; i < n; i++) {
 
            // Add current element to sum so far.
            currsum += arr[i];
 
            // If currsum is equal to desired sum,
            // then a new subarray is found. So
            // increase count of subarrays.
            if (currsum == sum)
                res++;
 
            // currsum exceeds given sum by currsum
            //  - sum. Find number of subarrays having
            // this sum and exclude those subarrays
            // from currsum by increasing count by
            // same amount.
            if (prevSum.containsKey(currsum - sum))
                res += prevSum.get(currsum - sum);
 
            // Add currsum value to count of
            // different values of sum.
            Integer count = prevSum.get(currsum);
            if (count == null)
                prevSum.put(currsum, 1);
            else
                prevSum.put(currsum, count + 1);
        }
 
        return res;
    }
 
    public static void main(String[] args)
    {
 
        int arr[] = { 10, 2, -2, -20, 10 };
        int sum = -10;
        int n = arr.length;
        System.out.println(findSubarraySum(arr, n, sum));
    }
}
 
// This code is contributed by Rituraj Jain


Python3
# Python3 program to find the number of
# subarrays with sum exactly equal to k.
from collections import defaultdict
 
# Function to find number of subarrays 
# with sum exactly equal to k.
def findSubarraySum(arr, n, Sum):
  
    # Dictionary to store number of subarrays
    # starting from index zero having 
    # particular value of sum.
    prevSum = defaultdict(lambda : 0)
   
    res = 0
   
    # Sum of elements so far.
    currsum = 0
   
    for i in range(0, n): 
   
        # Add current element to sum so far.
        currsum += arr[i]
   
        # If currsum is equal to desired sum,
        # then a new subarray is found. So
        # increase count of subarrays.
        if currsum == Sum: 
            res += 1        
   
        # currsum exceeds given sum by currsum  - sum.
        # Find number of subarrays having 
        # this sum and exclude those subarrays
        # from currsum by increasing count by 
        # same amount.
        if (currsum - Sum) in prevSum:
            res += prevSum[currsum - Sum]
           
   
        # Add currsum value to count of 
        # different values of sum.
        prevSum[currsum] += 1
      
    return res
  
if __name__ == "__main__":
 
    arr =  [10, 2, -2, -20, 10] 
    Sum = -10
    n = len(arr)
    print(findSubarraySum(arr, n, Sum))
     
# This code is contributed by Rituraj Jain


C#
// C# program to find number of subarrays
// with sum exactly equal to k.
using System;
using System.Collections.Generic;
 
class GFG {
    // Function to find number of subarrays
    // with sum exactly equal to k.
    public static int findSubarraySum(int[] arr,
                                      int n, int sum)
    {
 
        // HashMap to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        Dictionary prevSum = new Dictionary();
 
        int res = 0;
 
        // Sum of elements so far
        int currsum = 0;
 
        for (int i = 0; i < n; i++) {
 
            // Add current element to sum so far.
            currsum += arr[i];
 
            // If currsum is equal to desired sum,
            // then a new subarray is found. So
            // increase count of subarrays.
            if (currsum == sum)
                res++;
 
            // currsum exceeds given sum by currsum
            // - sum. Find number of subarrays having
            // this sum and exclude those subarrays
            // from currsum by increasing count by
            // same amount.
            if (prevSum.ContainsKey(currsum - sum))
                res += prevSum[currsum - sum];
 
            // Add currsum value to count of
            // different values of sum.
            if (!prevSum.ContainsKey(currsum))
                prevSum.Add(currsum, 1);
            else {
                int count = prevSum[currsum];
                prevSum[currsum] = count + 1;
            }
        }
        return res;
    }
 
    // Driver Code
    public static void Main()
    {
        int[] arr = { 10, 2, -2, -20, 10 };
        int sum = -10;
        int n = arr.Length;
        Console.Write(findSubarraySum(arr, n, sum));
    }
}
 
// This code is contributed by
// sanjeev2552


Javascript


输出:
3

高效的解决方案——
一个有效的解决方案是在遍历数组时,将迄今为止的总和存储在 currsum 中。此外,在地图中维护 currsum 的不同值的计数。如果 currsum 的值等于任何实例中所需的总和,则将子数组的计数加一。 currsum 的值通过 currsum – sum 超过了所需的总和。如果从 currsum 中删除此值,则可以获得所需的总和。从地图中找到先前找到的总和等于 currsum-sum 的子数组的数量。从当前子数组中排除所有这些子数组,得到具有所需总和的新子数组。因此,通过此类子数组的数量增加计数。请注意,当 currsum 等于所需的总和时,还要检查先前总和等于 0 的子阵列的数量。从当前子阵列中排除这些子阵列会产生具有所需总和的新子阵列。在这种情况下,将 count 增加总和为 0 的子数组的数量。

C++

// C++ program to find number of subarrays
// with sum exactly equal to k.
#include 
using namespace std;
 
// Function to find number of subarrays
// with sum exactly equal to k.
int findSubarraySum(int arr[], int n, int sum)
{
    // STL map to store number of subarrays
    // starting from index zero having
    // particular value of sum.
    unordered_map prevSum;
 
    int res = 0;
 
    // Sum of elements so far.
    int currsum = 0;
 
    for (int i = 0; i < n; i++) {
 
        // Add current element to sum so far.
        currsum += arr[i];
 
        // If currsum is equal to desired sum,
        // then a new subarray is found. So
        // increase count of subarrays.
        if (currsum == sum)
            res++;
 
        // currsum exceeds given sum by currsum
        //  - sum. Find number of subarrays having
        // this sum and exclude those subarrays
        // from currsum by increasing count by
        // same amount.
        if (prevSum.find(currsum - sum) != prevSum.end())
            res += (prevSum[currsum - sum]);
 
        // Add currsum value to count of
        // different values of sum.
        prevSum[currsum]++;
    }
 
    return res;
}
 
int main()
{
    int arr[] = { 10, 2, -2, -20, 10 };
    int sum = -10;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << findSubarraySum(arr, n, sum);
    return 0;
}

Java

// Java program to find number of subarrays
// with sum exactly equal to k.
import java.util.HashMap;
import java.util.Map;
 
public class GfG {
 
    // Function to find number of subarrays
    // with sum exactly equal to k.
    static int findSubarraySum(int arr[], int n, int sum)
    {
        // HashMap to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        HashMap prevSum = new HashMap<>();
 
        int res = 0;
 
        // Sum of elements so far.
        int currsum = 0;
 
        for (int i = 0; i < n; i++) {
 
            // Add current element to sum so far.
            currsum += arr[i];
 
            // If currsum is equal to desired sum,
            // then a new subarray is found. So
            // increase count of subarrays.
            if (currsum == sum)
                res++;
 
            // currsum exceeds given sum by currsum
            //  - sum. Find number of subarrays having
            // this sum and exclude those subarrays
            // from currsum by increasing count by
            // same amount.
            if (prevSum.containsKey(currsum - sum))
                res += prevSum.get(currsum - sum);
 
            // Add currsum value to count of
            // different values of sum.
            Integer count = prevSum.get(currsum);
            if (count == null)
                prevSum.put(currsum, 1);
            else
                prevSum.put(currsum, count + 1);
        }
 
        return res;
    }
 
    public static void main(String[] args)
    {
 
        int arr[] = { 10, 2, -2, -20, 10 };
        int sum = -10;
        int n = arr.length;
        System.out.println(findSubarraySum(arr, n, sum));
    }
}
 
// This code is contributed by Rituraj Jain

蟒蛇3

# Python3 program to find the number of
# subarrays with sum exactly equal to k.
from collections import defaultdict
 
# Function to find number of subarrays 
# with sum exactly equal to k.
def findSubarraySum(arr, n, Sum):
  
    # Dictionary to store number of subarrays
    # starting from index zero having 
    # particular value of sum.
    prevSum = defaultdict(lambda : 0)
   
    res = 0
   
    # Sum of elements so far.
    currsum = 0
   
    for i in range(0, n): 
   
        # Add current element to sum so far.
        currsum += arr[i]
   
        # If currsum is equal to desired sum,
        # then a new subarray is found. So
        # increase count of subarrays.
        if currsum == Sum: 
            res += 1        
   
        # currsum exceeds given sum by currsum  - sum.
        # Find number of subarrays having 
        # this sum and exclude those subarrays
        # from currsum by increasing count by 
        # same amount.
        if (currsum - Sum) in prevSum:
            res += prevSum[currsum - Sum]
           
   
        # Add currsum value to count of 
        # different values of sum.
        prevSum[currsum] += 1
      
    return res
  
if __name__ == "__main__":
 
    arr =  [10, 2, -2, -20, 10] 
    Sum = -10
    n = len(arr)
    print(findSubarraySum(arr, n, Sum))
     
# This code is contributed by Rituraj Jain

C#

// C# program to find number of subarrays
// with sum exactly equal to k.
using System;
using System.Collections.Generic;
 
class GFG {
    // Function to find number of subarrays
    // with sum exactly equal to k.
    public static int findSubarraySum(int[] arr,
                                      int n, int sum)
    {
 
        // HashMap to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        Dictionary prevSum = new Dictionary();
 
        int res = 0;
 
        // Sum of elements so far
        int currsum = 0;
 
        for (int i = 0; i < n; i++) {
 
            // Add current element to sum so far.
            currsum += arr[i];
 
            // If currsum is equal to desired sum,
            // then a new subarray is found. So
            // increase count of subarrays.
            if (currsum == sum)
                res++;
 
            // currsum exceeds given sum by currsum
            // - sum. Find number of subarrays having
            // this sum and exclude those subarrays
            // from currsum by increasing count by
            // same amount.
            if (prevSum.ContainsKey(currsum - sum))
                res += prevSum[currsum - sum];
 
            // Add currsum value to count of
            // different values of sum.
            if (!prevSum.ContainsKey(currsum))
                prevSum.Add(currsum, 1);
            else {
                int count = prevSum[currsum];
                prevSum[currsum] = count + 1;
            }
        }
        return res;
    }
 
    // Driver Code
    public static void Main()
    {
        int[] arr = { 10, 2, -2, -20, 10 };
        int sum = -10;
        int n = arr.Length;
        Console.Write(findSubarraySum(arr, n, sum));
    }
}
 
// This code is contributed by
// sanjeev2552

Javascript


输出:
3

时间复杂度: O(n)
辅助空间: O(n)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程