【问题标题】:closest to zero [absolute value] sum of consecutive subsequence of a sequence of real values最接近零 [绝对值] 实数值序列的连续子序列的总和
【发布时间】:2013-06-04 11:25:35
【问题描述】:

这对我来说是一个算法游乐场!我已经看到处理最大连续子序列的这个问题的变体,但这也是另一个变体。 正式的定义: 给定A[1..n],找到ij,这样abs(A[i]+A[i+1]+...+A[j]) 最接近于零。

我想知道如何获得O(n log^2 n),甚至O(n log n) 解决方案。

【问题讨论】:

  • 我认为您正在寻找负数和正数之间的最小距离,首先查看 i=j;您将它们与 0 本身进行比较
  • 我一得到答案就从cs网站上删除了! tanx 提到!

标签: algorithm sequence dynamic-programming divide-and-conquer


【解决方案1】:
  1. 计算累计和。
  2. 排序。
  3. 找到差异最小的顺序对。
function leastSubsequenceSum(values) {
    var n = values.length;

    // Store the cumulative sum along with the index.
    var sums = [];
    sums[0] = { index: 0, sum: 0 };
    for (var i = 1; i <= n; i++) {
        sums[i] = {
            index: i,
            sum: sums[i-1].sum + values[i-1]
        };
    }

    // Sort by cumulative sum
    sums.sort(function (a, b) {
        return a.sum == b.sum ? b.index - a.index : a.sum - b.sum;
    });

    // Find the sequential pair with the least difference.
    var bestI = -1;
    var bestDiff = null;
    for (var i = 1; i <= n; i++) {
        var diff = Math.abs(sums[i-1].sum - sums[i].sum);
        if (bestDiff === null || diff < bestDiff) {
            bestDiff = diff;
            bestI = i;
        }
    }

    // Just to make sure start < stop
    var start = sums[bestI-1].index;
    var stop = sums[bestI].index;
    if (start > stop) {
        var tmp = start;
        start = stop;
        stop = tmp;
    }

    return [start, stop-1, bestDiff];
}

示例:

>>> leastSubsequenceSum([10, -5, 3, -4, 11, -4, 12, 20]);
[2, 3, 1]

>>> leastSubsequenceSum([5, 6, -1, -9, -2, 16, 19, 1, -4, 9]);
[0, 4, 1]

>>> leastSubsequenceSum([3, 16, 8, -10, -1, -8, -3, 10, -2, -4]);
[6, 9, 1]

在第一个示例中,[2, 3, 1] 表示从索引23(含)的总和,您得到1 的绝对总和:

[10, -5, 3, -4, 11, -4, 12, 20]
         ^^^^^

【讨论】:

  • 那是很棒的 js 代码,太棒了!有没有其他设计方法,比如使用 AVL 树?!我听说这是可能的,我真的很想知道如何。
  • 我不知道。如果是这样,那实现起来会更加复杂,并且在速度或内存方面不会为您带来任何好处。
猜你喜欢
  • 2023-03-07
  • 2021-10-18
  • 1970-01-01
  • 2017-04-27
  • 1970-01-01
  • 1970-01-01
  • 2022-12-20
  • 2019-09-06
  • 2023-03-27
相关资源
最近更新 更多