📜  计算给定总和的最大非重叠子数组

📅  最后修改于: 2021-10-26 05:55:59             🧑  作者: Mango

给定一个由N 个整数和一个整数target组成的数组arr[] ,任务是找到最大数量的非空非重叠子数组,使得每个子数组中数组元素的总和等于target

例子:

方法:为了获得与目标总和不重叠的最小子数组,目标是使用前缀总和技术。请按照以下步骤解决问题:

  1. 将到目前为止计算的所有总和存储在 Map mp 中,键作为前缀的总和,直到该索引和值作为具有该总和的子数组的结束索引。
  2. 如果直到索引i前缀和,比如说sum ,等于target ,检查sum – target 是否存在于Map 中
  3. 如果map 中存在sum – targetmp[sum – target] = idx ,则表示来自[idx + 1, i]的子数组的 sum等于target
  4. 现在对于非重叠子数组,维护一个额外的变量availIdx (最初设置为-1),并且仅当mp[sum – target] ≥availIdx时才从[idx + 1, i] 中获取子数组
  5. 每当找到这样的子数组时,增加答案并将availIdx的值更改为当前索引。
  6. 此外,对于不重叠的子数组,贪婪地取尽可能小的子数组总是有益的。因此,对于找到的每个前缀和,更新其在 Map 中的索引,即使它已经存在。
  7. 完成上述步骤后打印count的值。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to count maximum number
// of non-overlapping subarrays with
// sum equals to the target
int maximumSubarrays(int arr[], int N,
                     int target)
{
    // Stores the final count
    int ans = 0;
 
    // Next subarray should start
    // from index >= availIdx
    int availIdx = -1;
 
    // Tracks the prefix sum
    int cur_sum = 0;
 
    // Map to store the prefix sum
    // for respective indices
    unordered_map mp;
    mp[0] = -1;
 
    for (int i = 0; i < N; i++) {
 
        cur_sum += arr[i];
 
        // Check if cur_sum - target is
        // present in the array or not
        if (mp.find(cur_sum - target)
                != mp.end()
            && mp[cur_sum - target]
                   >= availIdx) {
 
            ans++;
            availIdx = i;
        }
 
        // Update the index of
        // current prefix sum
        mp[cur_sum] = i;
    }
 
    // Return the count of subarrays
    return ans;
}
 
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 2, -1, 4, 3,
                  6, 4, 5, 1 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Given sum target
    int target = 6;
 
    // Function Call
    cout << maximumSubarrays(arr, N,
                             target);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to count maximum number
// of non-overlapping subarrays with
// sum equals to the target
static int maximumSubarrays(int arr[], int N,
                            int target)
{
     
    // Stores the final count
    int ans = 0;
 
    // Next subarray should start
    // from index >= availIdx
    int availIdx = -1;
 
    // Tracks the prefix sum
    int cur_sum = 0;
 
    // Map to store the prefix sum
    // for respective indices
    HashMap mp = new HashMap();
    mp.put(0, 1);
 
    for(int i = 0; i < N; i++)
    {
        cur_sum += arr[i];
 
        // Check if cur_sum - target is
        // present in the array or not
        if (mp.containsKey(cur_sum - target) &&
            mp.get(cur_sum - target) >= availIdx)
        {
            ans++;
            availIdx = i;
        }
         
        // Update the index of
        // current prefix sum
        mp.put(cur_sum, i);
    }
 
    // Return the count of subarrays
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array arr[]
    int arr[] = { 2, -1, 4, 3,
                  6, 4, 5, 1 };
 
    int N = arr.length;
 
    // Given sum target
    int target = 6;
 
    // Function call
    System.out.print(maximumSubarrays(arr, N,
                                      target));
}
}
 
// This code is contributed by Amit Katiyar


Python3
# Python3 program for the above approach
 
# Function to count maximum number
# of non-overlapping subarrays with
# sum equals to the target
def maximumSubarrays(arr, N, target):
     
    # Stores the final count
    ans = 0
 
    # Next subarray should start
    # from index >= availIdx
    availIdx = -1
 
    # Tracks the prefix sum
    cur_sum = 0
 
    # Map to store the prefix sum
    # for respective indices
    mp = {}
    mp[0] = -1
 
    for i in range(N):
        cur_sum += arr[i]
 
        # Check if cur_sum - target is
        # present in the array or not
        if ((cur_sum - target) in mp and
          mp[cur_sum - target] >= availIdx):
            ans += 1
            availIdx = i
 
        # Update the index of
        # current prefix sum
        mp[cur_sum] = i
 
    # Return the count of subarrays
    return ans
 
# Driver Code
if __name__ == '__main__':
     
    # Given array arr[]
    arr = [ 2, -1, 4, 3,
            6, 4, 5, 1 ]
 
    N = len(arr)
 
    # Given sum target
    target = 6
 
    # Function call
    print(maximumSubarrays(arr, N, target))
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to count maximum number
// of non-overlapping subarrays with
// sum equals to the target
static int maximumSubarrays(int []arr, int N,
                            int target)
{
  // Stores the readonly count
  int ans = 0;
 
  // Next subarray should start
  // from index >= availIdx
  int availIdx = -1;
 
  // Tracks the prefix sum
  int cur_sum = 0;
 
  // Map to store the prefix sum
  // for respective indices
  Dictionary mp = new Dictionary();
  mp.Add(0, 1);
 
  for(int i = 0; i < N; i++)
  {
    cur_sum += arr[i];
 
    // Check if cur_sum - target is
    // present in the array or not
    if (mp.ContainsKey(cur_sum - target) &&
        mp[cur_sum - target] >= availIdx)
    {
      ans++;
      availIdx = i;
    }
 
    // Update the index of
    // current prefix sum
    if(mp.ContainsKey(cur_sum))
      mp[cur_sum] = i;
    else
      mp.Add(cur_sum, i);
  }
 
  // Return the count of subarrays
  return ans;
}
 
// Driver Code
public static void Main(String[] args)
{   
  // Given array []arr
  int []arr = {2, -1, 4, 3,
               6, 4, 5, 1};
   
  int N = arr.Length;
 
  // Given sum target
  int target = 6;
 
  // Function call
  Console.Write(maximumSubarrays(arr, N,
                                 target));
}
}
 
// This code is contributed by Princi Singh


Javascript


输出:
3

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

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