📌  相关文章
📜  计数具有与子数组长度相同的模K的子数组

📅  最后修改于: 2021-05-04 18:14:05             🧑  作者: Mango

给定一个整数K和一个由N个正整数组成的数组arr [] ,任务是找到其求和模K等于子数组大小的子数组的数量。

例子:

天真的方法:最简单的方法是找到给定数组的前缀和,然后生成前缀和数组的所有子数组,并对那些求和K等于该子数组的长度的子数组进行计数。打印获得的子数组的最终计数。

下面是上述方法的实现:

C++
// C++ program of the above approach
 
#include 
using namespace std;
 
// Function that counts the subarrays
// having sum modulo k equal to the
// length of subarray
 
long long int countSubarrays(
    int a[], int n, int k)
{
 
    // Stores the count
    // of subarrays
    int ans = 0;
 
    // Stores prefix sum
    // of the array
    vector pref;
    pref.push_back(0);
 
    // Calculate prefix sum array
    for (int i = 0; i < n; i++)
        pref.push_back((a[i]
                        + pref[i])
                       % k);
 
    // Generate all the subarrays
    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j++) {
 
            // Check if this subarray is
            // a valid subarray or not
            if ((pref[j] - pref[i - 1] + k) % k
                == j - i + 1) {
                ans++;
            }
        }
    }
 
    // Total count of subarrays
    cout << ans << ' ';
}
 
// Driver Code
int main()
{
    // Given arr[]
    int arr[] = { 2, 3, 5, 3, 1, 5 };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Given K
    int K = 4;
 
    // Function Call
    countSubarrays(arr, N, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG{
     
// Function that counts the subarrays
// having sum modulo k equal to the
// length of subarray
static void countSubarrays(int a[], int n,
                           int k)
{
     
    // Stores the count
    // of subarrays
    int ans = 0;
   
    // Stores prefix sum
    // of the array
    ArrayList pref = new ArrayList<>();
    pref.add(0);
   
    // Calculate prefix sum array
    for(int i = 0; i < n; i++)
        pref.add((a[i] + pref.get(i)) % k);
   
    // Generate all the subarrays
    for(int i = 1; i <= n; i++)
    {
        for(int j = i; j <= n; j++)
        {
             
            // Check if this subarray is
            // a valid subarray or not
            if ((pref.get(j) -
                 pref.get(i - 1) + k) %
                     k == j - i + 1)
            {
                ans++;
            }
        }
    }
   
    // Total count of subarrays
    System.out.println(ans);
}
 
// Driver Code
public static void main (String[] args)
throws java.lang.Exception
{
     
    // Given arr[]
    int arr[] = { 2, 3, 5, 3, 1, 5 };
     
    // Size of the array
    int N = arr.length;
     
    // Given K
    int K = 4;
     
    // Function call
    countSubarrays(arr, N, K);
}
}
 
// This code is contributed by bikram2001jha


Python3
# Python3 program for the above approach
  
# Function that counts the subarrays
# having sum modulo k equal to the
# length of subarray
def countSubarrays(a, n, k):
  
    # Stores the count
    # of subarrays
    ans = 0
  
    # Stores prefix sum
    # of the array
    pref = []
    pref.append(0)
  
    # Calculate prefix sum array
    for i in range(n):
        pref.append((a[i] + pref[i]) % k)
  
    # Generate all the subarrays
    for i in range(1, n + 1, 1):
        for j in range(i, n + 1, 1):
  
            # Check if this subarray is
            # a valid subarray or not
            if ((pref[j] -
                 pref[i - 1] + k) %
                      k == j - i + 1):
                ans += 1
             
    # Total count of subarrays
    print(ans, end = ' ')
 
# Driver Code
 
# Given arr[]
arr = [ 2, 3, 5, 3, 1, 5 ]
  
# Size of the array
N = len(arr)
  
# Given K
K = 4
  
# Function call
countSubarrays(arr, N, K)
 
# This code is contributed by sanjoy_62


C#
// C# program for the above approach 
using System;
using System.Collections.Generic;
 
class GFG{
  
// Function that counts the subarrays
// having sum modulo k equal to the
// length of subarray
static void countSubarrays(int[] a, int n,
                            int k)
{
     
    // Stores the count
    // of subarrays
    int ans = 0;
    
    // Stores prefix sum
    // of the array
    List pref = new List();
    pref.Add(0);
    
    // Calculate prefix sum array
    for(int i = 0; i < n; i++)
        pref.Add((a[i] + pref[i]) % k);
    
    // Generate all the subarrays
    for(int i = 1; i <= n; i++)
    {
        for(int j = i; j <= n; j++)
        {
             
            // Check if this subarray is
            // a valid subarray or not
            if ((pref[j] -
                 pref[i - 1] + k) %
                      k == j - i + 1)
            {
                ans++;
            }
        }
    }
    
    // Total count of subarrays
    Console.WriteLine(ans);
}
  
// Driver Code
public static void Main ()
{
     
    // Given arr[]
    int[] arr = { 2, 3, 5, 3, 1, 5 };
      
    // Size of the array
    int N = arr.Length;
      
    // Given K
    int K = 4;
      
    // Function call
    countSubarrays(arr, N, K);
}
}
 
// This code is contributed by sanjoy_62


C++
// C++ program of the above approach
 
#include 
using namespace std;
 
// Function that counts the subarrays
// s.t. sum of elements in the subarray
// modulo k is equal to size of subarray
long long int countSubarrays(
    int a[], int n, int k)
{
    // Stores the count of (pref[i] - i) % k
    unordered_map cnt;
 
    // Stores the count of subarray
    long long int ans = 0;
 
    // Stores prefix sum of the array
    vector pref;
    pref.push_back(0);
 
    // Find prefix sum array
    for (int i = 0; i < n; i++)
        pref.push_back((a[i]
                        + pref[i])
                       % k);
 
    // Base Condition
    cnt[0] = 1;
 
    for (int i = 1; i <= n; i++) {
 
        // Remove the index at present
        // after K indices from the
        // current index
        int remIdx = i - k;
 
        if (remIdx >= 0) {
            cnt[(pref[remIdx]
                 - remIdx % k + k)
                % k]--;
        }
 
        // Update the answer for subarrays
        // ending at the i-th index
        ans += cnt[(pref[i]
                    - i % k + k)
                   % k];
 
        // Add the calculated value of
        // current index to count
        cnt[(pref[i] - i % k + k) % k]++;
    }
 
    // Print the count of subarrays
    cout << ans << ' ';
}
 
// Driver Code
int main()
{
    // Given arr[]
    int arr[] = { 2, 3, 5, 3, 1, 5 };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Given K
    int K = 4;
 
    // Function Call
    countSubarrays(arr, N, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG{
     
// Function that counts the subarrays
// having sum modulo k equal to the
// length of subarray
   
static void countSubarrays(int a[], int n,
                                    int k)
{
     
    // Stores the count of (pref[i] - i) % k
    HashMap cnt = new HashMap<>();
   
    // Stores the count of subarray
    long  ans = 0;
     
    // Stores prefix sum of the array
    ArrayList pref = new ArrayList<>();
    pref.add(0);
     
    // Find prefix sum array
    for(int i = 0; i < n; i++)
        pref.add((a[i] + pref.get(i)) % k);
   
    // Base Condition
    cnt.put(0, 1);
   
    for(int i = 1; i <= n; i++)
    {
         
        // Remove the index at present
        // after K indices from the
        // current index
        int remIdx = i - k;
   
        if (remIdx >= 0)
        {
            if (cnt.containsKey((pref.get(remIdx) -
                                   remIdx % k + k) % k))
                cnt.put((pref.get(remIdx) -
                          remIdx % k + k) % k,
                cnt.get((pref.get(remIdx) -
                          remIdx % k + k) % k) - 1);
                 
            else
                cnt.put((pref.get(remIdx) -
                          remIdx % k + k) % k, -1);
        }
   
        // Update the answer for subarrays
        // ending at the i-th index
        if (cnt.containsKey((pref.get(i) -
                              i % k + k) % k))
            ans += cnt.get((pref.get(i) -
                             i % k + k) % k);
   
        // Add the calculated value of
        // current index to count
        if (cnt.containsKey((pref.get(i) -
                           i % k + k) % k))
            cnt.put((pref.get(i) -
                      i % k + k) % k,
            cnt.get((pref.get(i) -
                 i % k + k) % k) + 1);
        else
            cnt.put((pref.get(i) -
                      i % k + k) % k, 1);
    }
   
    // Print the count of subarrays
    System.out.println(ans);
}
   
// Driver Code
public static void main (String[] args)
throws java.lang.Exception
{
     
    // Given arr[]
    int arr[] = { 2, 3, 5, 3, 1, 5 };
     
    // Size of the array
    int N = arr.length;
     
    // Given K
    int K = 4;
     
    // Function call
    countSubarrays(arr, N, K);
}
}
 
// This code is contributed by bikram2001jha


Python3
# Python3 program of the above approach
 
# Function that counts the subarrays
# s.t. sum of elements in the subarray
# modulo k is equal to size of subarray
def countSubarrays(a, n, k):
 
    # Stores the count of (pref[i] - i) % k
    cnt = {}
  
    # Stores the count of subarray
    ans = 0
  
    # Stores prefix sum of the array
    pref = []
    pref.append(0)
  
    # Find prefix sum array
    for i in range(n):
        pref.append((a[i] + pref[i]) % k)
  
    # Base Condition
    cnt[0] = 1
  
    for i in range(1, n + 1):
     
        # Remove the index at present
        # after K indices from the
        # current index
        remIdx = i - k
  
        if (remIdx >= 0):
            if ((pref[remIdx] -
                   remIdx % k + k) % k in cnt):
                cnt[(pref[remIdx] -
                       remIdx % k + k) % k] -= 1
            else:
                cnt[(pref[remIdx] -
                       remIdx % k + k) % k] = -1
                 
        # Update the answer for subarrays
        # ending at the i-th index
        if (pref[i] - i % k + k) % k in cnt:
            ans += cnt[(pref[i] - i % k + k) % k]
  
        # Add the calculated value of
        # current index to count
        if (pref[i] - i % k + k) % k in cnt:
            cnt[(pref[i] - i % k + k) % k] += 1
        else:
            cnt[(pref[i] - i % k + k) % k] = 1
     
    # Print the count of subarrays
    print(ans, end = ' ')
 
# Driver code 
 
# Given arr[]
arr = [ 2, 3, 5, 3, 1, 5 ]
 
# Size of the array
N = len(arr)
 
# Given K
K = 4
 
# Function call
countSubarrays(arr, N, K)
 
# This code is contributed by divyeshrabadiya07


C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
     
// Function that counts the subarrays
// having sum modulo k equal to the
// length of subarray
static void countSubarrays(int []a, int n,
                           int k)
{
  // Stores the count of
  // (pref[i] - i) % k
  Dictionary cnt = new Dictionary();
   
  // Stores the count of subarray
  long ans = 0;
 
  // Stores prefix sum of the array
  List pref = new List();
  pref.Add(0);
 
  // Find prefix sum array
  for(int i = 0; i < n; i++)
    pref.Add((a[i] + pref[i]) % k);
 
  // Base Condition
  cnt.Add(0, 1);
 
  for(int i = 1; i <= n; i++)
  {
    // Remove the index at present
    // after K indices from the
    // current index
    int remIdx = i - k;
 
    if (remIdx >= 0)
    {
      if (cnt.ContainsKey((pref[remIdx] -
                           remIdx % k + k) % k))
        cnt[(pref[remIdx] -
             remIdx % k + k) % k] = cnt[(pref[remIdx] -
                                    remIdx % k + k) % k] - 1;
 
      else
        cnt.Add((pref[remIdx] -
                 remIdx % k + k) % k, -1);
    }
 
    // Update the answer for subarrays
    // ending at the i-th index
    if (cnt.ContainsKey((pref[i] -
                         i % k + k) % k))
      ans += cnt[(pref[i] -
                  i % k + k) % k];
 
    // Add the calculated value of
    // current index to count
    if (cnt.ContainsKey((pref[i] -
                         i % k + k) % k))
      cnt[(pref[i] -
           i % k + k) % k] = cnt[(pref[i] -
                                  i % k + k) % k] + 1;
    else
      cnt.Add((pref[i] -
               i % k + k) % k, 1);
  }
 
  // Print the count of subarrays
  Console.WriteLine(ans);
}
   
// Driver Code
public static void Main(String[] args)
 
{
  // Given []arr
  int []arr = {2, 3, 5, 3, 1, 5};
 
  // Size of the array
  int N = arr.Length;
 
  // Given K
  int K = 4;
 
  // Function call
  countSubarrays(arr, N, K);
}
}
 
// This code is contributed by Rajput-Ji


输出:
5







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

高效的方法:想法是生成给定数组的前缀和,然后问题减少到子数组的数量,使得(pref [j] – pref [i])%K等于(j – i) ,其中j > i并且(j − i)≤K。以下是步骤:

  • 创建一个辅助数组pref [] ,它存储给定数组的前缀和。
  • 为了计算满足上述方程式的子数组,方程式可写为:
  • 遍历前缀数组pref [],并为每个索引j将计数(pref [j] – j)%K存储在映射M中。
  • 对于上述步骤中的每个元素pref [i] ,将计数更新为M [(pref [i] – i%K + K)%K],并增加(pref [i] – i%K + K)%的频率地图M中的K。
  • 完成上述步骤后,打印子数组的计数值。

下面是上述方法的实现:

C++

// C++ program of the above approach
 
#include 
using namespace std;
 
// Function that counts the subarrays
// s.t. sum of elements in the subarray
// modulo k is equal to size of subarray
long long int countSubarrays(
    int a[], int n, int k)
{
    // Stores the count of (pref[i] - i) % k
    unordered_map cnt;
 
    // Stores the count of subarray
    long long int ans = 0;
 
    // Stores prefix sum of the array
    vector pref;
    pref.push_back(0);
 
    // Find prefix sum array
    for (int i = 0; i < n; i++)
        pref.push_back((a[i]
                        + pref[i])
                       % k);
 
    // Base Condition
    cnt[0] = 1;
 
    for (int i = 1; i <= n; i++) {
 
        // Remove the index at present
        // after K indices from the
        // current index
        int remIdx = i - k;
 
        if (remIdx >= 0) {
            cnt[(pref[remIdx]
                 - remIdx % k + k)
                % k]--;
        }
 
        // Update the answer for subarrays
        // ending at the i-th index
        ans += cnt[(pref[i]
                    - i % k + k)
                   % k];
 
        // Add the calculated value of
        // current index to count
        cnt[(pref[i] - i % k + k) % k]++;
    }
 
    // Print the count of subarrays
    cout << ans << ' ';
}
 
// Driver Code
int main()
{
    // Given arr[]
    int arr[] = { 2, 3, 5, 3, 1, 5 };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Given K
    int K = 4;
 
    // Function Call
    countSubarrays(arr, N, K);
 
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG{
     
// Function that counts the subarrays
// having sum modulo k equal to the
// length of subarray
   
static void countSubarrays(int a[], int n,
                                    int k)
{
     
    // Stores the count of (pref[i] - i) % k
    HashMap cnt = new HashMap<>();
   
    // Stores the count of subarray
    long  ans = 0;
     
    // Stores prefix sum of the array
    ArrayList pref = new ArrayList<>();
    pref.add(0);
     
    // Find prefix sum array
    for(int i = 0; i < n; i++)
        pref.add((a[i] + pref.get(i)) % k);
   
    // Base Condition
    cnt.put(0, 1);
   
    for(int i = 1; i <= n; i++)
    {
         
        // Remove the index at present
        // after K indices from the
        // current index
        int remIdx = i - k;
   
        if (remIdx >= 0)
        {
            if (cnt.containsKey((pref.get(remIdx) -
                                   remIdx % k + k) % k))
                cnt.put((pref.get(remIdx) -
                          remIdx % k + k) % k,
                cnt.get((pref.get(remIdx) -
                          remIdx % k + k) % k) - 1);
                 
            else
                cnt.put((pref.get(remIdx) -
                          remIdx % k + k) % k, -1);
        }
   
        // Update the answer for subarrays
        // ending at the i-th index
        if (cnt.containsKey((pref.get(i) -
                              i % k + k) % k))
            ans += cnt.get((pref.get(i) -
                             i % k + k) % k);
   
        // Add the calculated value of
        // current index to count
        if (cnt.containsKey((pref.get(i) -
                           i % k + k) % k))
            cnt.put((pref.get(i) -
                      i % k + k) % k,
            cnt.get((pref.get(i) -
                 i % k + k) % k) + 1);
        else
            cnt.put((pref.get(i) -
                      i % k + k) % k, 1);
    }
   
    // Print the count of subarrays
    System.out.println(ans);
}
   
// Driver Code
public static void main (String[] args)
throws java.lang.Exception
{
     
    // Given arr[]
    int arr[] = { 2, 3, 5, 3, 1, 5 };
     
    // Size of the array
    int N = arr.length;
     
    // Given K
    int K = 4;
     
    // Function call
    countSubarrays(arr, N, K);
}
}
 
// This code is contributed by bikram2001jha

Python3

# Python3 program of the above approach
 
# Function that counts the subarrays
# s.t. sum of elements in the subarray
# modulo k is equal to size of subarray
def countSubarrays(a, n, k):
 
    # Stores the count of (pref[i] - i) % k
    cnt = {}
  
    # Stores the count of subarray
    ans = 0
  
    # Stores prefix sum of the array
    pref = []
    pref.append(0)
  
    # Find prefix sum array
    for i in range(n):
        pref.append((a[i] + pref[i]) % k)
  
    # Base Condition
    cnt[0] = 1
  
    for i in range(1, n + 1):
     
        # Remove the index at present
        # after K indices from the
        # current index
        remIdx = i - k
  
        if (remIdx >= 0):
            if ((pref[remIdx] -
                   remIdx % k + k) % k in cnt):
                cnt[(pref[remIdx] -
                       remIdx % k + k) % k] -= 1
            else:
                cnt[(pref[remIdx] -
                       remIdx % k + k) % k] = -1
                 
        # Update the answer for subarrays
        # ending at the i-th index
        if (pref[i] - i % k + k) % k in cnt:
            ans += cnt[(pref[i] - i % k + k) % k]
  
        # Add the calculated value of
        # current index to count
        if (pref[i] - i % k + k) % k in cnt:
            cnt[(pref[i] - i % k + k) % k] += 1
        else:
            cnt[(pref[i] - i % k + k) % k] = 1
     
    # Print the count of subarrays
    print(ans, end = ' ')
 
# Driver code 
 
# Given arr[]
arr = [ 2, 3, 5, 3, 1, 5 ]
 
# Size of the array
N = len(arr)
 
# Given K
K = 4
 
# Function call
countSubarrays(arr, N, K)
 
# This code is contributed by divyeshrabadiya07

C#

// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
     
// Function that counts the subarrays
// having sum modulo k equal to the
// length of subarray
static void countSubarrays(int []a, int n,
                           int k)
{
  // Stores the count of
  // (pref[i] - i) % k
  Dictionary cnt = new Dictionary();
   
  // Stores the count of subarray
  long ans = 0;
 
  // Stores prefix sum of the array
  List pref = new List();
  pref.Add(0);
 
  // Find prefix sum array
  for(int i = 0; i < n; i++)
    pref.Add((a[i] + pref[i]) % k);
 
  // Base Condition
  cnt.Add(0, 1);
 
  for(int i = 1; i <= n; i++)
  {
    // Remove the index at present
    // after K indices from the
    // current index
    int remIdx = i - k;
 
    if (remIdx >= 0)
    {
      if (cnt.ContainsKey((pref[remIdx] -
                           remIdx % k + k) % k))
        cnt[(pref[remIdx] -
             remIdx % k + k) % k] = cnt[(pref[remIdx] -
                                    remIdx % k + k) % k] - 1;
 
      else
        cnt.Add((pref[remIdx] -
                 remIdx % k + k) % k, -1);
    }
 
    // Update the answer for subarrays
    // ending at the i-th index
    if (cnt.ContainsKey((pref[i] -
                         i % k + k) % k))
      ans += cnt[(pref[i] -
                  i % k + k) % k];
 
    // Add the calculated value of
    // current index to count
    if (cnt.ContainsKey((pref[i] -
                         i % k + k) % k))
      cnt[(pref[i] -
           i % k + k) % k] = cnt[(pref[i] -
                                  i % k + k) % k] + 1;
    else
      cnt.Add((pref[i] -
               i % k + k) % k, 1);
  }
 
  // Print the count of subarrays
  Console.WriteLine(ans);
}
   
// Driver Code
public static void Main(String[] args)
 
{
  // Given []arr
  int []arr = {2, 3, 5, 3, 1, 5};
 
  // Size of the array
  int N = arr.Length;
 
  // Given K
  int K = 4;
 
  // Function call
  countSubarrays(arr, N, K);
}
}
 
// This code is contributed by Rajput-Ji
输出:
5







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