📜  将数组拆分为三个具有连续Sum的连续子数组的方法数量

📅  最后修改于: 2021-04-24 16:39:09             🧑  作者: Mango

给定由非负整数组成的数组arr [] ,任务是找到将数组拆分为三个非空连续子数组的方式,以使它们各自的元素和按递增顺序排列。

例子:

方法:想法是使用“前缀和后缀求和数组”和“两个指针”技术。请按照以下步骤解决问题:

  • 生成前缀和数组和后缀和数组。
  • 初始化两个指针se以找到第二个子数组的总和。
  • 遍历阵列,增量curr_subarray_sumARR并[e]同时curr_subarray_sum小于prefix_sum [S – 1],并保持递增
  • 每当curr_subarray_sum≥prefix_sum [s – 1]时,请检查curr_subarray_sum是否≤suffix_sum [e] 。如果发现为真,则增加count
  • curr_subarray_sum减少arr [s]并增加s
  • 重复上述步骤,最后打印计数

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
#include
using namespace std;
  
// Function to count the number of ways
// to split array into three contigous
// subarrays of the required type
int findCount(int arr[], int n)
{
  
    // Stores the prefix sums
    int prefix_sum[n];
  
    prefix_sum[0] = arr[0];
  
    for(int i = 1; i < n; i++)
        prefix_sum[i] = prefix_sum[i - 1] + arr[i];
  
    // Stores the suffix sums
    int suffix_sum[n];
  
    suffix_sum[n - 1] = arr[n - 1];
  
    for(int i = n - 2; i >= 0; i--)
        suffix_sum[i] = suffix_sum[i + 1] + arr[i];
  
    int s = 1, e = 1;
    int curr_subarray_sum = 0, count = 0;
  
    // Traverse the given array
    while (s < n - 1 && e < n - 1)
    {
          
        // Updating curr_subarray_sum until
        // it is less than prefix_sum[s-1]
        while (e < n - 1 && curr_subarray_sum < 
               prefix_sum[s - 1]) 
        {
            curr_subarray_sum += arr[e++];
        }
  
        if (curr_subarray_sum <= suffix_sum[e])
        {
              
            // Increase count
            count++;
        }
  
        // Decrease curr_subarray_sum by arr[s[]
        curr_subarray_sum -= arr[s++];
    }
  
    // Return count
    return count;
}
  
// Driver code
int32_t main()
{
    int arr[] = { 2, 3, 1, 7 };
    int n = sizeof arr / sizeof arr[0];
      
    cout << (findCount(arr, n));
}
  
// This code is contributed by Stream_Cipher


Java
// Java Program to implement
// the above approach
import java.io.*;
import java.util.*;
  
class GFG {
  
    // Function to count the number of ways
    // to split array into three contigous
    // subarrays of the required type
    static int findCount(int arr[], int n)
    {
  
        // Stores the prefix sums
        int[] prefix_sum = new int[n];
  
        prefix_sum[0] = arr[0];
  
        for (int i = 1; i < n; i++)
            prefix_sum[i]
                = prefix_sum[i - 1] + arr[i];
  
        // Stores the suffix sums
        int[] suffix_sum = new int[n];
  
        suffix_sum[n - 1] = arr[n - 1];
  
        for (int i = n - 2; i >= 0; i--)
            suffix_sum[i]
                = suffix_sum[i + 1] + arr[i];
  
        int s = 1, e = 1;
        int curr_subarray_sum = 0, count = 0;
  
        // Traverse the given array
        while (s < n - 1 && e < n - 1) {
  
            // Updating curr_subarray_sum until
            // it is less than prefix_sum[s-1]
            while (e < n - 1
                   && curr_subarray_sum
                          < prefix_sum[s - 1]) {
                curr_subarray_sum += arr[e++];
            }
  
            if (curr_subarray_sum <= suffix_sum[e]) {
                // Increase count
                count++;
            }
  
            // Decrease curr_subarray_sum by arr[s[]
            curr_subarray_sum -= arr[s++];
        }
  
        // Return count
        return count;
    }
  
    // Driver Code
    public static void main(String args[])
    {
  
        int[] arr = { 2, 3, 1, 7 };
        int n = arr.length;
        System.out.println(findCount(arr, n));
    }
}


Python3
# Python3 program to implement
# the above approach
  
# Function to count the number of ways
# to split array into three contigous
# subarrays of the required type
def findCount(arr, n):
  
    # Stores the prefix sums
    prefix_sum = [0 for x in range(n)]
    prefix_sum[0] = arr[0]
      
    for i in range(1, n):
        prefix_sum[i] = prefix_sum[i - 1] + arr[i]
      
    # Stores the suffix sums
    suffix_sum = [0 for x in range(n)]
      
    suffix_sum[n - 1] = arr[n - 1]
      
    for i in range(n - 2, -1, -1):
        suffix_sum[i] = suffix_sum[i + 1] + arr[i]
      
    s = 1
    e = 1
    curr_subarray_sum = 0
    count = 0
      
    #Traverse the given array
    while (s < n - 1 and e < n - 1):
          
        # Updating curr_subarray_sum until
        # it is less than prefix_sum[s-1]
        while (e < n - 1 and 
               curr_subarray_sum < prefix_sum[s - 1]):
            curr_subarray_sum += arr[e]
            e += 1
                  
        if (curr_subarray_sum <= suffix_sum[e]):
              
            # Increase count
            count += 1
                  
        # Decrease curr_subarray_sum by arr[s[]
        curr_subarray_sum -= arr[s]
        s += 1
      
    # Return count
    return count
      
# Driver code
arr = [ 2, 3, 1, 7 ]
n = len(arr) 
  
print(findCount(arr, n))
  
# This code is contributed by Stream_Cipher


C#
// C# Program to implement
// the above approach
using System;
class GFG{
  
  // Function to count the number of ways
  // to split array into three contigous
  // subarrays of the required type
  static int findCount(int []arr, int n)
  {
  
    // Stores the prefix sums
    int[] prefix_sum = new int[n];
  
    prefix_sum[0] = arr[0];
  
    for (int i = 1; i < n; i++)
      prefix_sum[i] = prefix_sum[i - 1] + arr[i];
  
    // Stores the suffix sums
    int[] suffix_sum = new int[n];
  
    suffix_sum[n - 1] = arr[n - 1];
  
    for (int i = n - 2; i >= 0; i--)
      suffix_sum[i] = suffix_sum[i + 1] + arr[i];
  
    int s = 1, e = 1;
    int curr_subarray_sum = 0, count = 0;
  
    // Traverse the given array
    while (s < n - 1 && e < n - 1) 
    {
  
      // Updating curr_subarray_sum until
      // it is less than prefix_sum[s-1]
      while (e < n - 1 && 
             curr_subarray_sum < prefix_sum[s - 1]) 
      {
        curr_subarray_sum += arr[e++];
      }
  
      if (curr_subarray_sum <= suffix_sum[e])
      {
        // Increase count
        count++;
      }
  
      // Decrease curr_subarray_sum by arr[s[]
      curr_subarray_sum -= arr[s++];
    }
  
    // Return count
    return count;
  }
  
  // Driver Code
  public static void Main(String []args)
  {
  
    int[] arr = { 2, 3, 1, 7 };
    int n = arr.Length;
    Console.WriteLine(findCount(arr, n));
  }
}
  
// This code is contributed by Rohit_ranjan


输出:
2

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