【问题标题】:find the maximum value of sum of subarray modulo M求子数组模 M 和的最大值
【发布时间】:2016-06-08 11:14:01
【问题描述】:

问题是 - 给你一个大小为 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);

【问题讨论】:

    标签: arrays dynamic-programming


    【解决方案1】:

    在模算术中,将除数添加到结果中并没有什么不同。例如,-1 (mod N)N-1 相同。 在您的算法中,M - up + sum 是从 sum 中减去 up,由于它始终为负数,因此添加 M 以使结果为正数。

    算法在做什么?

    • 使用变量sum 遍历数组并保持运行总和
    • 继续将运行中的sum 存储到TreeSet 中。这个想法是能够在O(log N) 中提取一个总和。 sum - (any number from sumSet) 是子数组的总和。如果结果为负,则将M 相加得出子数组的正和。
    • sumSet 中提取大于sum 的最小整数。为什么?可能的最大总和是最小的负数。可能的最大模和是M - 1。当sum - up 等于-1 时获得。
    • 如果没有这样的先前总和,请将当前的 sumbest 进行比较。
    • 否则,将sum - up + Mbest 进行比较。

    复杂度:O(n log n)

    【讨论】:

    • 很好的解释..正在考虑进入 O(n),但因为树集的 O(nlogn)。但它比生成所有子集并检查会导致 O(n2)
    猜你喜欢
    • 2015-09-15
    • 1970-01-01
    • 2012-06-07
    • 2018-08-17
    • 2014-09-04
    • 1970-01-01
    • 2015-02-09
    • 2018-12-28
    • 1970-01-01
    相关资源
    最近更新 更多