给定大小为N的数组arr []和元素K。任务是找到给定数组的子数组的数量,以使当其元素之和除以K时的余数等于子数组中元素的数量。
例子:
Input: arr[] = {1, 4, 2, 3, 5}, K = 4
Output: 4
{1}, {1, 4, 2}, {4, 2} and {5}
are the only valid subarrays.
Input: arr[] = {4, 2, 4, 2, 4, 2, 4, 2}, K = 4
Output: 7
方法:让我们定义一个序列S n ,使得S i = A 1 + A 2 +···+ A i和S 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)