题目描述:
给你一个正整数 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; } };
|