Form the largest number by swapping one pair of digits You are given a number. You are given the opportunity to swap only once to produce the largest number.




My approach was to use buckets whose values were their indexes and their locations were their values. 

I walked the array checking if the largest value was greater than the current value. 

If the current value was smaller I would decrement the largest value. Checking if it existed and that, that bucket was in a location greater than the current location in the iteration.  

At which point I would know the bucket's location and that it contained the largest value outside a successive set and the nearest lowest value it would replace, to produce the largest number.  

Analysis:


Creating Buckets: O(n) time and O(n) space
Walking Values Space and Time: O(1) +  finding the lowest high and swapping: O(1)
Total: O(n)




const maximumSwap = function(array) {
  array = array.toString().split('');
  const buckets = []
  for (let location = 0; location &lt; array.length; location++) {
    buckets[array[location]] = location
  }
  let largest = buckets.length - 1
  for (let current_location = 0; current_location &lt; array.length; current_location++) {
    let current_val = array[current_location]
    for (; largest &gt; current_val; largest--) {
      if (buckets[largest] &gt; current_location) {
        array[current_location] = [array[buckets[largest]], array[buckets[largest]] = array[current_location]][0]
        return +array.join('')
      }
    }
  }
  return +array.join('')
};

console.log(maximumSwap(99739))
console.log(maximumSwap(9273))
console.log(maximumSwap(9732))
Style critique

Either terminate your statements consistently with semicolons, or not at all.

If you're going to use const to define the function, then I suggest using the arrow notation as well, instead of the function keyword.

The variable names could be improved:


Why is the function's parameter called array?  It's clearly supposed to be a number.
After splitting the digits, what does array mean, and what does it contain?  I'd rename it to digits.
What are the buckets?  I suggest renaming it to lastIndex.
Instead of location and current_location, I'd just use i, which is a conventional variable name to use for an array index.  (Also, the underscore is unconventional in JavaScript.)
largest doesn't remain the largest digit of the number.  Perhaps wantDigit would be a better name, since it's the digit that we would like to put at the current index, if possible.


The nastiest line of code is the one where you perform the swap:


array[current_location] = [array[buckets[largest]], array[buckets[largest]] = array[current_location]][0]



A better way to do parallel assignment would be to use destructuring assignment:



let array = ['a', 'b', 'c'];
[array[0], array[2]] = [array[2], array[0]];
console.log(array);




But here, you don't even need to do parallel assignments, because you have already stored the values to be swapped in other variables:


array[buckets[largest]], as an rvalue, is just largest.  (With the renamings I proposed above, it would have been digits[lastIndex[wantDigit]], which might make it more obvious that it's actually just wantDigit.)
array[current_location], as an rvalue, is just current_val.


So, just write two simple and clear assignment statements instead.

If no swap occurred, then you can just return the original number.



const maximumSwap = (number) =&gt; {
    let digits = number.toString().split('');
    let lastIndex = [];
    for (let i = 0; i &lt; digits.length; i++) {
        lastIndex[digits[i]] = i;
    }
    let wantDigit = lastIndex.length - 1;
    for (let i = 0; i &lt; digits.length; i++) {
        for (let iDigit = digits[i]; iDigit &lt; wantDigit; wantDigit--) {
            if (i &lt; lastIndex[wantDigit]) {
                digits[i] = wantDigit;
                digits[lastIndex[wantDigit]] = iDigit;
                return +digits.join('');
            }
        }
    }
    return number;
};

console.log(maximumSwap(99739));
console.log(maximumSwap(9273));
console.log(maximumSwap(9732));




Complexity analysis

Your algorithm is pretty efficient, and I couldn't find any significant optimizations to make.

Be careful to specify what you mean by "n".  You probably used it to mean the length of the input number.  (If I had to choose my conventions, I'd say instead that the input number itself is n, and its length is d = log10 n.)

Creating the buckets takes O(n) time, because location loops up to array.length.  But I would say that it takes O(1) space, since the length of buckets will not exceed 10.

Walking the values clearly takes more than O(1) time, because the outer loop is O(n): current_location iterates up to array.length.  The inner loop, which executes at most 10 times, can be said to take O(1) time.

Altogether, then, the algorithm takes O(n) time and O(1) space.