【问题标题】:Insertion sort works with small arrays but not bigger ones插入排序适用于小数组,但不适用于较大的数组
【发布时间】:2016-08-25 23:18:06
【问题描述】:

我正在 JS 中处理这个 hackerrank challenge 并且我正在实现插入排序。使用我的解决方案,它适用于较小的数组,但不适用于具有 100 多个索引的较大数组。我无法弄清楚为什么我的实现不起作用。我在互联网上搜索过,大多数插入排序的实现与我的相同。这是我正在使用的代码:

function processData(input) {
    //Enter your code here
    input = input.split("\n");
    var array = input[1].split(" ");
    insertionSort(array);
} 

function insertionSort(array){
    for(var i=1; i<array.length; i++){
        for(var j=i; j>0; j--){
            if(array[j-1] > array[j]){
                var temp = array[j-1];
                array[j-1] = array[j];
                array[j] = temp;
            }
        }
        console.log(array.toString().replace(/,/g," "));
    }
}

编辑:这是一个函数排序失败的例子。

输入:

406 157 415 318 472 46 252 187 364 481 450 90 390 35 452 74 196 312 142 160 143 220 483 392 443 488 79 234 68 150 356 496 69 88 177 12 288 120 222 270 441 422 103 321 65 316 448 331 117 183 184 128 323 141 467 31 172 48 95 359 239 209 398 99 440 171 86 233 293 162 121 61 317 52 54 273 30 226 421 64 204 444 418 275 263 108 10 149 497 20 97 136 139 200 266 238 493 22 17 39

输出:

10 103 108 117 12 120 121 128 136 139 141 142 143 149 150 157 160 162 17 171 172 177 183 184 187 196 20 200 204 209 22 220 222 226 233 234 238 239 252 263 266 270 273 275 288 293 30 31 312 316 317 318 321 323 331 35 356 359 323 319 390 392 344 444 450 452 444 472 484 484 481 481 484 484 484 481 484 481 493 493 493 493 484 493 494 484 493 496 497 5254 614S 64 64 79 88 69 74 79 86 88 88 80 95 97 99

【问题讨论】:

  • 你能提供一个失败的例子吗?
  • 仔细观察你的内部 for 循环。它包含一个 if 语句。您是否会期望 if 语句在循环的某些迭代中为真,然后在某些迭代中为假,然后再次为真的情况发生?或者你会期望一旦 if 语句开始返回 false,它就再也不会返回 true?
  • 不是你在排序字符串的问题吗?
  • @Hamms 我不确定我是否在关注,抱歉我的大脑在试图弄清楚这一点后有点糊涂。
  • @jeffcarey 你是对的。我将 if 语句更改为解析双方的 int 并且它起作用了。没有意识到这一点,我感到很愚蠢。

标签: javascript algorithm sorting


【解决方案1】:

我参加过许多有竞争力的编程竞赛,包括一两次 Hackerrank。

首先,我怀疑内存是个问题。据我所知,您使用的是线性内存量,并且由于数组的大小最多为 1000,因此您不可能超过几 MB。

其次,我怀疑有错误的答案问题,因为算法看起来是正确的。

这给我们留下了一个潜在的问题:超过了时间限制。这可能是由于各种原因,首先想到的是使用的语言。据我所知,Hackerrank 每次测试都有相同的时间限制,与编程语言无关。由于问题来自算法领域,与解释型的 Javascript 相比,很可能在用 C/C++ 编写的模型解决方案之后校准时间限制,这是一种编译和快速的语言。在其他平台上,有时会提到由于时间限制是根据 C++ 模型解决方案校准的,如果您使用不同的语言,可能会或可能不会适应时间限制。

如果你真的想用 Javascript 解决这个问题,你需要进行微优化。我注意到的两个是在 a[j] > a[j - 1] 时放置一个 break 语句(进一步检查是没有意义的,因为前缀已经排序)和优化 console.log 操作。一般来说,IO 操作是所有语言中最昂贵的。尝试将所有中间数组(100 万个小数字,大约 5-6MB,因此内存不是问题)缓冲到一个字符串中,然后只调用一次 console.log。

另外,我不知道字符串的替换方法效率如何,尤其是在使用正则表达式的情况下,即使非常简单。因为你使用的是解释型语言,而且时间限制很紧,即使在实际应用中差异不大,在这种情况下,我们需要尽可能多地压缩 CPU 时间,甚至 1.5 的常数也可以重大。尝试自己将数字连接到字符串。更好的是,将 -10000 到 10000 的所有数字的字符串表示形式预处理为字符串数组,然后将它们连接起来。很可能“toString”没有针对整数进行优化,并且执行许多模运算,这很昂贵,并且当您执行数百万次时可能会成为瓶颈。

试试这些优化,如果你解决了,请告诉我们!

编辑:抱歉,我没有在 cmets 中注意到您收到错误的答案,因为您没有正确解析数组。如果你愿意,我可以删除答案。

【讨论】:

    猜你喜欢
    • 2021-08-25
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    相关资源
    最近更新 更多