文章目录
- Tag
- 题目来源
- 题目解读
- 解题思路
- 方法一:下一个排列
- 写在最后
Tag
【单调栈】【数组】【字符串】
题目来源
556. 下一个更大元素 III
题目解读
找出大于整数的最小整数,这个最小整数必须由原来整数中出现的数字组成。
解题思路
方法一:下一个排列
我们将 n
转换成字符串之后,本题就是在求字符数组的 31. 下一个排列。直接贴出代码如下:
实现代码
class Solution {
public:int nextGreaterElement(int n) {string str = to_string(n);int strLen = str.size();int i = strLen - 2;// 找str中违反字符数字是降序的第一个字符(从后往前的第一个)while (i >= 0 && str[i] >= str[i+1]) {--i;}if (i < 0) return -1; // str 字符数字是降序的,无答案// 找 str[i] 右侧比 str[i] 大的最小的字符int j = strLen - 1;while (j >= 0 && str[i] >= str[j]) {--j;}swap(str[i], str[j]);reverse(str.begin() + i + 1, str.end()); // 也可以进行排序long res = stol(str);return res > INT_MAX ? -1 : res;}
};
单调栈
找 str[i]
右侧比 str[i]
大的最小的字符,可以使用单调栈来解决。直接贴上代码:
class Solution {
public:int nextGreaterElement(int n) {string str = to_string(n);int strLen = str.size();int i = strLen - 1;int idx = 0; // 找 `str[i]` 右侧比 `str[i]` 大的最小的字符stack<int> stk;for (; i >= 0; --i) {// 如果从后往前一直是递增的就一直加入栈,直到遇到违反递增的第一个字符,下标为i,找到idxwhile(!stk.empty() && str[i] < str[stk.top()]) {idx = stk.top();stk.pop();}// 将 str[i] 与其右侧比 str[i] 大的最小字符交换if (idx != 0) {swap(str[i], str[idx]);break;}stk.push(i);}// idx 一直没有更新,说明 str 从后往前一直是递增的if (idx == 0) return -1;reverse(str.begin() + i + 1, str.end()); // 也可以进行排序long res = stol(str);return res > INT_MAX ? -1 : res;}
};
复杂度分析
时间复杂度: O ( l o g n ) O(logn) O(logn), m m m 是整数 n
转化成字符串后的长度,其实有 m = logn
,本题需要对长度为 m m m 的字符进行一次遍历操作,因此时间复杂度为 O ( m ) O(m) O(m),即 O ( l o g n ) O(logn) O(logn)。
空间复杂度: O ( l o g n ) O(logn) O(logn),使用的额外字符串,长度为 O ( l o g n ) O(logn) O(logn)。
写在最后
如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。
最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。