【问题标题】:Children candies Hackerrank challenge : optimising the solution儿童糖果 Hackerrank 挑战:优化解决方案
【发布时间】:2019-08-17 16:28:07
【问题描述】:

我正在尝试解决 JavaScript 中的 hackerrank 挑战,尽管对于大多数测试实例,我的解决方案都表现得很好,但我一直在为其中一些实例超时(Hackerrank 将其设置为 10 秒以应对 JavaScript 挑战)。问题描述如下:

有 N 个孩子排成一排。最初第 i 个孩子有 a[i] 糖果。有些孩子比其他孩子有更多的糖果。你有 确保每个学生都有相同数量的糖果。在一个 你可以告诉其中一个孩子给一个糖果 左边的邻居,或右边的邻居。你做了多少次手术 需要确保每个学生都有相同数量的糖果吗?打印 尽可能少的操作数。输入是多行 字符串,其中第一行包含一个整数 N,下一行 行包含 N 个空格分隔的整数。

我通过计算应该给每个孩子多少糖果来解决这个问题,然后迭代包含糖果数量的数组,或者从最右边的位置抓取糖果(以防孩子没有足够的糖果) ),或将糖果传递到正确的位置(以防孩子需要更多)

这是我用于挑战的代码:

function processData(input) {
    let tmp = input.split(/\n| /),
        n = tmp[0]    

    tmp.shift()  // remove first element from tmp (the N variable)

    let s=0, a = tmp.map(function(ai) {novo=parseInt(ai, 10);s+=novo;return(novo)}),
        obj = s/n, ops = 0

    for(var i=0; i<n; i++) {

        if(a[i] > obj) {
            let moved = a[i]-obj
            a[i]-=moved
            a[i+1]+=moved
            ops+=moved
        }
        else {
            for(var j=i+1; a[i] != obj; j++) {


                if(a[j]===0) {
                    ops++
                }
                else {
                    let moved = Math.min(a[j], obj-a[i])
                    a[i]+=moved
                    a[j]-=moved
                    ops+=moved
                }
            }        
        }

        //console.log(a)
    }

    console.log(ops)
}

知道问题出在哪里吗?

您将如何优化我的代码?

挑战链接:https://www.hackerrank.com/contests/coc1/challenges/candies-1

编辑 经过一些优化后,我的解决方案现在失败了 3 个测试用例(与之前由于超时而失败的相同)。这不是性能问题

【问题讨论】:

  • 尝试复制确切的问题陈述。您的问题描述的第二句话与挑战中的第二句话有非常不同的含义。
  • 已编辑!感谢您注意到该错误
  • 主要问题是您有三个嵌套循环,使运行时类似于 O(n^3)。您应该能够在一次数据传递中做到这一点。首先计算每个孩子最终会得到多少糖果。然后扫描孩子们。可以这样想:如果第一个孩子的 k 颗糖果低于平均水平,则必须将这些 k 颗糖果运送到那里。所以你至少需要k步。现在去下一个孩子,你能从那里得到它们吗,也许是部分的?如果没有,您将需要为第一个孩子额外移动 k 步,以及孩子 2 缺少的糖果。

标签: javascript algorithm optimization


【解决方案1】:

问题是,您需要多少步才能计算每个孩子的平均数。

比如拿这行孩子,

1  4  2  7  1

从第一个孩子开始,看看它有多少项目以及它应该有多少项目。取(绝对)差来计算动作,给第一个孩子取平均值。下一个孩子获得第一个孩子的增量。在这种情况下,给出两个项目后,它就有两个项目。

然后查看该行中的下一个孩子。重复上述操作,您将在一个循环中获得所有孩子的移动次数。

   children     moves 
--------------- -----
 1  4  2  7  1     2
<3  2> 2  7  1     1
 3 <3  1> 7  1     2
 3  3 <3  5> 1     2
 3  3  3 <3  3>
--------------- -----
                   7

<x  y> denotes a group of changing values

示例 2

   children     moves 
--------------- -----
 7  4  2  1  1     4
<3  8> 2  1  1     5
 3 <3  7> 1  1     4
 3  3 <3  5> 1     2
 3  3  3 <3  3>
--------------- -----
                  15

function processData(input) {
    var [length, ...values] = input.split(/\\n|\s/),
        i,
        moves = 0,
        value = 0,
        sum = 0,
        avg;
        
    for (i = 0; i < +length; i++) sum += +values[i];
    avg = sum / length;

    for (i = 0; i < length - 1; i++) {
        value += +values[i];
        moves += Math.abs(value - avg);
        value -= avg;
    }
    
    return moves;
}

console.log(processData('5\n1 4 2 7 1')); //  7
console.log(processData('5\n7 4 2 1 1')); // 15
console.log(processData('3\n1 2 3'));     //  2

【讨论】:

  • 哎呀,这和我的+1解决方案一样,它和@binte的不一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2017-06-23
  • 2022-01-16
  • 1970-01-01
  • 2017-08-19
  • 2010-09-06
相关资源
最近更新 更多