Search code examples
javascriptalgorithmbacktracking

JS Minimum So Far Backtracking Algorithm Bug


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}` );


Solution

  • 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.