0%

556. 下一个更大元素 III

556.下一个更大元素 III

题目描述:

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

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

数据范围:

$1\le n \le 2^{31} - 1$

题解:

下一个更大元素系列。

496. 下一个更大元素 I 单调栈,单调减栈。

503. 下一个更大元素 II 单调栈,循环数组,二倍长度。

556.下一个更大元素 III 也就是下一个排列,31. 下一个排列

可以直接使用库函数 next_permutation 生成下一个排列。

下一个排列,比当前排列大,可以选左侧一个数 $x$,右侧一个数 $y$,然后交换 $x,y$。需要满足 $x < y$。而且 $x$ 越往后越好,$y$ 越小越好。即需要找到一个数左侧的比他小的第一个数。

可以使用单调增栈,然后从后往前遍历,找到第一组数字 $(x,y)$,然后交换,最后需要对 $x, end$ 之间的数字排序。

库函数:

使用 to_string 可以快速将别的类型转为 string。使用 $stoi, stol, stof, stod$ 等可以快速将 string 转为数字。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
auto optimize_cpp_stdio = []()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
class Solution
{
public:
const static int maxn = 1e5 + 10;
const static int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int nextGreaterElement(int n)
{
string s = to_string(n);
int size = s.length();
// 从后往前单调增?
vector<int> st(size);
int top = -1;
vector<int> ans;
bool flag = false;
int swapi, swapj;
for (int i = size - 1; i >= 0; --i)
{
while (top >= 0 && s[st[top]] > s[i])
{
flag = true;
swapi = i;
swapj = st[top];
--top;
}
if (flag)
break;
st[++top] = i;
}
if (!flag)
return -1;
swap(s[swapi], s[swapj]);
sort(s.begin() + swapi + 1, s.end());
long long sum = stol(s.c_str());
if (sum > INT_MAX || sum <= n)
return -1;
return sum;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
auto optimize_cpp_stdio = []()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
class Solution
{
public:
const static int maxn = 1e5 + 10;
const static int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int nextGreaterElement(int n)
{
string s = to_string(n);
int size = s.length();
// 从后往前单调增?
int i = size - 2;
while(i >= 0 && s[i] >= s[i + 1])
--i;
if(i == -1) return -1;
int j = size - 1;
while(j >= 0 && s[i] >= s[j])
--j;
if(j == -1)
return -1;
swap(s[i], s[j]);
reverse(s.begin() + i + 1, s.end());
long long sum = stol(s.c_str());
if (sum > INT_MAX || sum <= n)
return -1;
return sum;
}
};