📌  相关文章
📜  对子数组进行计数,以使元素之和除以K后的余数给出元素的计数

📅  最后修改于: 2021-05-05 01:38:23             🧑  作者: Mango

给定大小为N的数组arr []和元素K。任务是找到给定数组的子数组的数量,以使当其元素之和除以K时的余数等于子数组中元素的数量。

例子:

方法:让我们定义一个序列S n ,使得S i = A 1 + A 2 +···+ A iS 0 = 0 。然后,可以将连续子序列A i + 1 ,…,A j有效的条件表示为(S j – S i )%K = j – i
然后可以将此方程式转换为以下等效条件:
(S j – j)%K =(S i – i)%K并且j – i
因此,对于每个j(1≤j≤N) ,计算j – K ,以使(S j – j)%K =(S i – i)%K 。对于j ,需要搜索的段是(j – K,j) ,对于j + 1 ,它是(j – K + 1,j + 1) ,并且它们在最左边和最右边仅相差一个元素,因此,为了在搜索j元素之后搜索(j + 1)元素,仅丢弃最左边的元素并添加最右边的元素。通过使用关联数组(例如C++中的map或Python的dict)管理S i – i的数量,可以快速执行丢弃或添加操作。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the number of subarrays
// of the given array such that the remainder
// when dividing the sum of its elements
// by K is equal to the number of its elements
int sub_arrays(int a[], int n, int k)
{
 
    // To store prefix sum
    int sum[n + 2] = { 0 };
 
    for (int i = 0; i < n; i++) {
 
        // We are dealing with zero
        // indexed array
        a[i]--;
 
        // Taking modulus value
        a[i] %= k;
 
        // Prefix sum
        sum[i + 1] += sum[i] + a[i];
        sum[i + 1] %= k;
    }
 
    // To store the required answer, the left
    // index and the right index
    int ans = 0, l = 0, r = 0;
 
    // To store si - i value
    map mp;
 
    for (int i = 0; i < n + 1; i++) {
 
        // Include sum
        ans += mp[sum[i]];
        mp[sum[i]]++;
 
        // Increment the right index
        r++;
 
        // If subarray has at least
        // k elements
        if (r - l >= k) {
            mp[sum[l]]--;
            l++;
        }
    }
 
    // Return the required answer
    return ans;
}
 
// Driver code
int main()
{
    int a[] = { 1, 4, 2, 3, 5 };
    int n = sizeof(a) / sizeof(a[0]);
 
    int k = 4;
 
    // Function call
    cout << sub_arrays(a, n, k);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class gfg
{
     
    // Function to return the number of subarrays
    // of the given array such that the remainder
    // when dividing the sum of its elements
    // by K is equal to the number of its elements
    static int sub_arrays(int []a, int n, int k)
    {
     
        // To store prefix sum
        int sum[] = new int[n + 2] ;
         
        for (int i = 0; i < n+2; i++)
        {
            sum[i] = 0;
        }
         
        for (int i = 0; i < n; i++)
        {
     
            // We are dealing with zero
            // indexed array
            a[i]--;
     
            // Taking modulus value
            a[i] %= k;
     
            // Prefix sum
            sum[i + 1] += sum[i] + a[i];
            sum[i + 1] %= k;
        }
     
        // To store the required answer, the left
        // index and the right index
        int ans = 0, l = 0, r = 0;
     
        // To store si - i value
        HashMap mp = new HashMap();
     
        for (int i = 0; i < n + 1; i++)
        {
            mp.put(sum[i], 0);
        }
        int temp;
         
        for (int i = 0; i < n + 1; i++)
        {
     
            // Include sum
            ans += (int)mp.get(sum[i]);
            temp =(int)mp.get(sum[i]) + 1;
            mp.put(sum[i], temp);
     
            // Increment the right index
            r++;
     
            // If subarray has at least
            // k elements
            if (r - l >= k)
            {
                //mp[sum[l]]--;
                temp = (int)mp.get(sum[l]) - 1;
                mp.put(sum[l], temp);
                l++;
            }
        }
     
        // Return the required answer
        return ans;
    }
     
    // Driver code
    public static void main(String args[])
    {
        int []a = { 1, 4, 2, 3, 5 };
         
        int n = a.length;
     
        int k = 4;
     
        // Function call
        System.out.print(sub_arrays(a, n, k));
     
    }
}
 
// This code is contributed by AnkitRai01


Python3
# Python3 implementation of the approach
 
# Function to return the number of
# subarrays of the given array
# such that the remainder when dividing
# the sum of its elements by K is
# equal to the number of its elements
def sub_arrays(a, n, k):
 
    # To store prefix sum
    sum = [0 for i in range(n + 2)]
 
    for i in range(n):
 
        # We are dealing with zero
        # indexed array
        a[i] -= 1
 
        # Taking modulus value
        a[i] %= k
 
        # Prefix sum
        sum[i + 1] += sum[i] + a[i]
        sum[i + 1] %= k
 
    # To store the required answer,
    # the left index and the right index
    ans = 0
    l = 0
    r = 0
 
    # To store si - i value
    mp = dict()
 
    for i in range(n + 1):
 
        # Include sum
        if sum[i] in mp:
            ans += mp[sum[i]]
        mp[sum[i]] = mp.get(sum[i], 0) + 1
 
        # Increment the right index
        r += 1
 
        # If subarray has at least
        # k elements
        if (r - l >= k):
            mp[sum[l]] -= 1
            l += 1
 
    # Return the required answer
    return ans
 
# Driver code
a = [1, 4, 2, 3, 5]
n = len(a)
 
k = 4
 
# Function call
print(sub_arrays(a, n, k))
 
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class gfg
{
    // Function to return the number of subarrays
    // of the given array such that the remainder
    // when dividing the sum of its elements
    // by K is equal to the number of its elements
    static int sub_arrays(int []a, int n, int k)
    {
     
        // To store prefix sum
        int []sum = new int[n + 2] ;
         
        for (int i = 0; i < n + 2; i++)
        {
            sum[i] = 0;
        }
         
        for (int i = 0; i < n; i++)
        {
     
            // We are dealing with zero
            // indexed array
            a[i]--;
     
            // Taking modulus value
            a[i] %= k;
     
            // Prefix sum
            sum[i + 1] += sum[i] + a[i];
            sum[i + 1] %= k;
        }
     
        // To store the required answer, the left
        // index and the right index
        int ans = 0, l = 0, r = 0;
     
        // To store si - i value
        Dictionary mp = new Dictionary();
     
        for (int i = 0; i < n + 1; i++)
        {
            if(!mp.ContainsKey(sum[i]))
                mp.Add(sum[i], 0);
        }
        int temp;
         
        for (int i = 0; i < n + 1; i++)
        {
     
            // Include sum
            ans += (int)mp[sum[i]];
            temp =(int)mp[sum[i]] + 1;
            mp[sum[i]] = temp;
     
            // Increment the right index
            r++;
     
            // If subarray has at least
            // k elements
            if (r - l >= k)
            {
                //mp[sum[l]]--;
                temp = (int)mp[sum[l]] - 1;
                mp[sum[i]] = temp;
                l++;
            }
        }
     
        // Return the required answer
        return ans;
    }
     
    // Driver code
    public static void Main(String []args)
    {
        int []a = { 1, 4, 2, 3, 5 };
         
        int n = a.Length;
     
        int k = 4;
     
        // Function call
        Console.Write(sub_arrays(a, n, k));
    }
}
 
// This code is contributed by 29AjayKumar


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