下一个更大元素 III
描述
-
给你一个正整数 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;
}
922



被折叠的 条评论
为什么被折叠?



