Next smallest number. How to simplify finding the second index?

  • 0
    There is a function to find the next smallest number.
    function nextSmaller(n){
    let forv=[...`${n}`].map(Number), rev=[...`${n}`].map(Number).reverse(),
    let nn=Number([...forv.slice(0,idx1+1),...forv.slice(idx1-forv.length+1)
    return rev.findIndex((_,i,a)=>a[i-1]<a[i])==-1||`${nn}`.length!=`${n}`.length?-1:nn}
    console.log(nextSmaller(133232766512347))   //133232766475321

    On the right, we find the index of the first digit, which has a smaller digit on the right. This is idx1 // 9
    Then we find the index of the largest digit to the right of idx1 and less. This is idx2 // 13
    Swap these numbers.
    Next, we sort all the numbers after index 9 in descending order.
    Is it possible to simplify finding idx2?
    JavaScript Anonymous, Dec 30, 2018

  • 2 Answers
  • 0
    Well, naturally. By the logic of finding the first number, you can understand that all the numbers after it come in ascending order, so from the reverse find the index of the first number that is less than forv [idx1] and that's it. Naturally shielded by normal order.

    For the same reason, after the rearrangement, sorting the numbers in the reverse order is not required, the reverse is sufficient.

    Besides, forv is not needed here at all, just rev

    function nextSmaller(n){
    const rev = [...`${n}`].map(Number).reverse()
    const idx1 = rev.findIndex((v, i, a) => i && a[i-1] < v)

    if (idx1 < 0) return idx1

    const idx2 = rev.slice(0, idx1).findIndex(v => v < rev[idx1])
    if (idx2 < 0) return idx2;

    [rev[idx1], rev[idx2]] = [rev[idx2], rev[idx1]]

    const nn = +rev.slice(idx1).reverse().concat(rev.slice(0, idx1)).join('')
    return nn

    console.log(nextSmaller(133232766512347)) //133232766475321
    Hunter Logan

  • 0
    I suspect binary search will help here

Your Answer
To place the code, please use CodePen or similar tool. Thanks you!