I am trying to implement a backtracking algorithm in JS to find the minimum value possible by swapping k digits.
I can't see why my code doesn't work. If I log out the values for num
, it goes down to 159
but that doesn't get returned as the minSoFar, for some reason.
Any ideas please?
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}` );
It's failing to return correctly because the minSoFar that's assigned is local to the recursion frame it's in. Either (1) make minSoFar global to the recursion, or (2) make it a value in an object and pass the object (since those are passed by reference, the recursion frames would be amending the same value), or (3) actually compare the returned min rather than trying to assign it.
(3) means assign findMin( digits, n, k - 1, minSoFar )
to a local value, returning the best one from the loop.