JS 最小到目前为止回溯算法错误

Posted

技术标签:

【中文标题】JS 最小到目前为止回溯算法错误【英文标题】:JS Minimum So Far Backtracking Algorithm Bug 【发布时间】:2020-12-19 13:19:34 【问题描述】:

我正在尝试在 JS 中实现回溯算法,以通过交换 k 位来找到可能的最小值。

我不明白为什么我的代码不起作用。如果我注销 num 的值,它会下降到 159,但由于某种原因,它不会作为 minSoFar 返回。

有什么想法吗?

function swap( arr, i, j ) 
    const temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;


function findMin( digits, n, k, minSoFar ) 
    // Compare current number with minimum number so far
    const num = parseInt( digits.join( '' ) );

    if ( num < minSoFar ) 
    minSoFar = num;
    

    // base case - no more swaps allowed.
    if ( k < 1 ) 
    return minSoFar;
    


    // For each digit in the input string
    for ( let i = 0; i < n - 1; i++ ) 
    // compare the current digit with remaining digits
    for ( let j = i + 1; j < n; j++ ) 
        // if digit at i'th index is more than the digit at j'th index
        if ( digits[i] > digits[j] ) 
        // swap digits i and j
        swap( digits, i, j );

        // recur for remaining k - 1 swaps
        findMin( digits, n, k - 1, minSoFar );

        // backtrack - restore the string back
        swap( digits, i, j );
        
    
    
    return minSoFar;


let i = 951;
let k = 2;
let digits = Array.from( String( i ), Number );
let minimum = findMin( digits, digits.length, k, i );
console.log( `The minimum number formed by doing at most $k swaps is $minimum` );

【问题讨论】:

【参考方案1】:

它无法正确返回,因为分配的 minSoFar 是它所在的递归框架的本地。要么(1)使 minSoFar 对递归全局,要么(2)使其成为对象中的值并传递对象(因为这些是通过引用传递的,递归帧将修改相同的值),或者(3)实际比较返回的 min 而不是尝试分配它。

(3) 表示将findMin( digits, n, k - 1, minSoFar ) 分配给本地值,从循环中返回最佳值。

【讨论】:

所以我做了minSoFar = findMin( digits, n, k - 1, minSoFar );,它似乎有效。 @RobinAndrews,是的,这将是 (3) 的一个版本,因为 minSoFar 是框架的本地。 @RobinAndrews 在我看来,仅将返回值分配给 minSoFar 可能还不够。如果最后一个返回值恰好大于该迭代中的前一个值怎么办?人们需要保留其中最好的一个。 你能想出一个无法帮助我进一步探索的测试用例吗? @RobinAndrews 让我们这样说吧:如果无论如何我们总是返回 minSoFar 的最后一个赋值,为什么还要麻烦有两个嵌套循环呢?我们可以向后运行两个循环并返回第一个满足条件的交换,然后退出它。 (我建议它确实很重要。)

以上是关于JS 最小到目前为止回溯算法错误的主要内容,如果未能解决你的问题,请参考以下文章

应用回溯算法寻找毕业的最小学期数

DFS ( 深度优先/回溯算法 ) 一

[动态规划与回溯算法] 路径问题

[动态规划与回溯算法] 路径问题

LeetCode 140. 单词拆分 II(回溯算法和DFS解决)

两道关于回溯法,分支限界法的算法题