问题是 - 给你一个大小为N的数组和另一个整数M.你的目标是找到模数为M的子阵列之和的最大值。
If array is {3 3 9 9 5} and M is {7}
可能的子阵列
{3},{3},{9}.{9}.{5}
{3,3},{3,9},{9,9},{9,5}
{3,3,9},{3,9,9},{9,9,5}
{3,3,9,9},{3,9,9,5},{3,3,9,9,5}
其中模数7的最大可能总和为6.子阵列{3,3}具有最大总和。
我遇到了解决方案,但无法理解逻辑
static void solve(long M, long[] array){
TreeSet<Long> sumSet = new TreeSet<Long>();
long best = 0;
long sum = 0;
for(int i = 0; i < array.length; i++){
sum = (sum + array[i]) % M;
Long up = sumSet.higher(sum);
if(up == null){
best = Math.max(best,sum);
} else {
best = Math.max(best, M - up + sum);
}
sumSet.add(sum);
}
System.out.println(best);
}
该行意味着什么
best = Math.max(best, M - up + sum);
答案 0 :(得分:1)
在模运算中,将除数添加到结果中并没有什么区别。例如,-1 (mod N)
与N-1
相同。
在您的算法中,M - up + sum
从up
减去sum
,因为它总是为负数,所以添加M
以使结果为正。
算法正在做什么?
sum
sum
存储到TreeSet
。我们的想法是能够在O(log N)
中提取总和。 sum - (any number from sumSet)
是子数组的总和。如果结果为负,则加起来M
给出子数组的正和。 sum
中提取大于sumSet
的最小整数。为什么?可能的最大总和是最小的负数。可能的最大模数总和为M - 1
。它是在sum - up
等于-1
时获得的。 sum
与best
进行比较。sum - up + M
与best
进行比较。复杂性:O(n log n)