寻找全排列的下一个数

511 阅读1分钟

题目:一个整数所包含的数字的全部组合中,找到一个大于且仅大于原数的新整数

例如:输入 12345 返回 12354

输入 12354 返回 12435

输入 12435 返回 12453

解法:

思路:

1. 为了和原数接近,尽量保持高位不变,低位在最小的范围内变换顺序

2. 变换顺序的范围大小,取决于当前整数的逆序区域

例如:12354

54 为逆序区域,即当前这两位已经是最大组合,若想比原数大,则需要从倒数第三位开始改变

3. 倒数第三位是 3,则需要从逆序区域找到最小比 3 大的数字,与 3 交换位置

12453

4. 最后把逆序区域转换为 顺序,确保后两位尽可能的小

代码实现

    function findNearestNumber(num:number):number {
        let numArray = [...String(num)]
    
    
        // 1. 找到逆序区域边界
        let i = 0;
        for (let index = numArray.length; index > 0; index--) {
            if(Number(numArray[index - 1]) < Number(numArray[index])) {
                i = index
                break
            }
        }
        // 当前数字为最大值
        if(i === 0) {
            return num
        }
        // 2. 找到逆序区最小且比逆序区前一位大的数字 交换位置
        let min = numArray[i];
        let minIndex = i
        for (let index = i + 1; index < numArray.length; index++) {
            if(numArray[index] < min) {
                minIndex = index
            }
        }
        let temp = numArray[i-1]
        numArray[i-1] = numArray[minIndex]
        numArray[minIndex] = temp;
    
    
        //3. 逆序区域转换为顺序区域
        for (let index = i, j = numArray.length -1; index < j; index++, j--) {
            let temp = numArray[j];
            numArray[j] = numArray[index];
            numArray[index] = temp       
        }
    
        return Number(numArray.join(''))
    }

摘要总结自: 漫画算法 小灰的算法之旅