数据结构与算法之栈: LeetCode 556. 下一个更大元素 III (Ts版)

下一个更大元素 III

  • https://leetcode.cn/problems/next-greater-element-iii/description/

描述

  • 给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1

  • 注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1

示例 1

输入:n = 12
输出:21

示例 2

输入:n = 21
输出:-1

提示

  • 1 <= n <= 2 31 2^{31} 231 - 1

Typescript 版算法实现


1 ) 方案1:下一个排列

function nextGreaterElement(n: number): number {
    const MAX: number = 2147483647;
    // 将数字转换为字符数组
    const nums: string[] = [...('' + n)];

    // 找到第一个从右往左递减的位置
    let i: number = nums.length - 2;
    while (i >= 0 && nums[i] >= nums[i + 1]) {
        i--;
    }

    // 如果没有找到这样的位置,返回 -1
    if (i < 0) {
        return -1;
    }

    // 找到第一个比 nums[i] 大的元素并交换
    let j: number = nums.length - 1;
    while (j >= 0 && nums[i] >= nums[j]) {
        j--;
    }
    [nums[i], nums[j]] = [nums[j], nums[i]];

    // 反转 i+1 到末尾的部分
    reverse(nums, i + 1);

    // 将字符数组重新组合成数字
    const ans: number = parseInt(nums.join(''), 10);

    // 检查是否超出最大值限制
    return ans > MAX ? -1 : ans;
}

// 反转数组的一部分
function reverse(nums: string[], begin: number): void {
    let i: number = begin;
    let j: number = nums.length - 1;
    while (i < j) {
        [nums[i], nums[j]] = [nums[j], nums[i]];
        i++;
        j--;
    }
}

2 ) 方案2:数学

function nextGreaterElement(n: number): number {
    let x: number = n;
    let cnt: number = 1;
    const MAX: number = 2147483647; // math.MaxInt32 的值

    // 找到第一个从右往左递减的位置
    while (x >= 10 && Math.floor(x / 10) % 10 >= x % 10) {
        x = Math.floor(x / 10);
        cnt++;
    }

    x = Math.floor(x / 10);
    if (x === 0) {
        return -1;
    }

    const targetDigit: number = x % 10;
    let x2: number = n;
    let cnt2: number = 0;

    // 找到第一个比 targetDigit 大的数字
    while (x2 % 10 <= targetDigit) {
        x2 = Math.floor(x2 / 10);
        cnt2++;
    }

    // 把 x2%10 换到 targetDigit 上
    x += x2 % 10 - targetDigit;

    // 反转 n 末尾的 cnt 个数字拼接到 x 后
    for (let i = 0; i < cnt; i++) {
        let d: number = targetDigit;
        if (i !== cnt2) {
            d = n % 10;
        }
        if (x > Math.floor(MAX / 10) || (x === Math.floor(MAX / 10) && d > 7)) {
            return -1;
        }
        x = x * 10 + d;
        n = Math.floor(n / 10);
    }

    return x;
}

你可能感兴趣的:(Data,Structure,and,Algorithms,leetcode,算法)