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

📅  最后修改于: 2021-05-14 00:40:47             🧑  作者: Mango

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

例子:

的方法:为了得到具有总和目标的最小的非重叠子阵列中,目标是使用前缀和技术。请按照以下步骤解决问题:

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

下面是上述方法的实现:

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


输出:
3





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