Your code can be optimized a bit, for example, you can use the break statement in your inner loop to move to the next number as soon as you find out that the current one will not work (which should make it work in about half the cases, but for n like 91234567 ) is still pretty slow, but instead of n.toString().split("").length , a variable is used in the loop, so you only need to convert n to an array once.
function nextSmaller(n) { var nArray = n.toString().split("") var length = nArray.length; var minimumNum = 1 + Array(length).join('0') for(var i=n-1; i >= minimumNum; i--) { var newNumArray = i.toString().split(''); var counter = 0; for (var j=0; j<newNumArray.length; j++) { if (nArray.indexOf(newNumArray[j]) < 0) break; counter++ nArray.splice(nArray.indexOf(newNumArray[j]), 1) if (counter === length) { return i; } } nArray = n.toString().split(""); } return -1; }
There is a very efficient algorithm for computing the next permutation, which can be easily adapted to obtain the previous one (and returns -1 if the resulting permutation starts from 0 ). I adapted this algorithm for this:
[21,531,2071,912345678,9123545678,915345678].forEach( x => console.log( nextSmaller( x ) ) ); function nextSmaller(n) { const arr = ( n + '' ).split( '' ).map( Number );
source share