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 最小到目前为止回溯算法错误的主要内容,如果未能解决你的问题,请参考以下文章