You are given a 0-indexed integer array arr and an integer k. The array arr is circular. In other words, the first element of the array is the next element of the last element, and the last element of the array is the previous element of the first element.
You can do the following operation any number of times:
Pick any element from arr and increase or decrease it by 1.
Return _the minimum number of operations such that the sum of eachsubarray of length _kis equal.
Input: arr =[1,4,1,3], k =2Output: 1Explanation: we can do one operation on index 1 to make its value equal to 3.The array after the operation is[1,3,1,3]- Subarray starts at index 0is[1,3], and its sum is4- Subarray starts at index 1is[3,1], and its sum is4- Subarray starts at index 2is[1,3], and its sum is4- Subarray starts at index 3is[3,1], and its sum is4
Input: arr =[2,5,5,7], k =3Output: 5Explanation: we can do three operations on index 0 to make its value equal to 5 and two operations on index 3 to make its value equal to 5.The array after the operations is[5,5,5,5]- Subarray starts at index 0is[5,5,5], and its sum is15- Subarray starts at index 1is[5,5,5], and its sum is15- Subarray starts at index 2is[5,5,5], and its sum is15- Subarray starts at index 3is[5,5,5], and its sum is15
The key is that for all subarrays of length k to have equal sum in a circular array, elements at positions with the same index modulo gcd(n, k) must be made equal. For each group, the minimum number of operations is achieved by making all elements equal to the median of the group.
classSolution {
public:longlong makeSubKSumEqual(vector<int>& arr, int k) {
int n = arr.size(), g = gcd(n, k);
longlong ans =0;
for (int i =0; i < g; ++i) {
vector<int> vals;
for (int j = i; j < n; j += g) vals.push_back(arr[j]);
sort(vals.begin(), vals.end());
int m = vals.size();
int med = vals[m/2];
for (int v : vals) ans += abs(v - med);
}
return ans;
}
};
import java.util.*;
classSolution {
publiclongmakeSubKSumEqual(int[] arr, int k) {
int n = arr.length, g = gcd(n, k);
long ans = 0;
for (int i = 0; i < g; ++i) {
List<Integer> vals =new ArrayList<>();
for (int j = i; j < n; j += g) vals.add(arr[j]);
Collections.sort(vals);
int m = vals.size(), med = vals.get(m/2);
for (int v : vals) ans += Math.abs(v - med);
}
return ans;
}
intgcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
funmakeSubKSumEqual(arr: IntArray, k: Int): Long {
val n = arr.size
val g = gcd(n, k)
var ans = 0Lfor (i in0 until g) {
val vals = mutableListOf<Int>()
for (j in i until n step g) vals.add(arr[j])
vals.sort()
val med = vals[vals.size/2]
for (v in vals) ans += kotlin.math.abs(v - med)
}
return ans
}
fungcd(a: Int, b: Int): Int = if (b ==0) a else gcd(b, a % b)
}
1
2
3
4
5
6
7
8
9
10
11
from math import gcd
classSolution:
defmakeSubKSumEqual(self, arr: list[int], k: int) -> int:
n, g = len(arr), gcd(len(arr), k)
ans =0for i in range(g):
vals = [arr[j] for j in range(i, n, g)]
vals.sort()
med = vals[len(vals)//2]
ans += sum(abs(v - med) for v in vals)
return ans
impl Solution {
pubfnmake_sub_k_sum_equal(arr: Vec<i32>, k: i32) -> i64 {
fngcd(mut a: i32, mut b: i32) -> i32 { while b !=0 { let t = b; b = a % b; a = t; } a }
let n = arr.len();
let g = gcd(n asi32, k) asusize;
letmut ans =0i64;
for i in0..g {
letmut vals =vec![];
letmut j = i;
while j < n {
vals.push(arr[j]);
j += g;
}
vals.sort();
let med = vals[vals.len()/2];
for v in vals { ans += (v - med).abs() asi64; }
}
ans
}
}