每日算法系列【LeetCode 556】下一个更大元素 III

简介: 每日算法系列【LeetCode 556】下一个更大元素 III

题目描述

给定一个32位正整数 n,你需要找到最小的32位整数,其与 n 中存在的位数完全相同,并且其值大于n。如果不存在这样的32位整数,则返回-1。

示例1

输入:
12
输出:
21

示例2

输入:
21
输出:
-1

题解

首先要发现一个性质,如果调换两个数位之后,整个数字变大了,那说明第一个数位的数字小于第二个数位的数。所以我们只需要找到一个顺序对,调换它俩顺序就行了。

但是如果存在两个顺序对  和  ,那我们就要找  更大的那个,因为前面的尽量不动才会使调换后的数字最小。

如果  相同的话,就要在  右边找最小的使得  的数,这样  处的数字才是最小的,同时整体数字还会变大。

最后因为  处已经变大了,所以  后面的数字全部都要升序排列,这样整体数字才是最小的。

所以整体算法就有了,我们从右往左找,找到第一个上升的位置  ,也就是  。这样  右边就是降序了,不存在顺序对。然后在  右边的数字中二分查找最小的大于  的数  ,调换它俩位置。最后把  右边的数字变成升序即可。

代码

c++

class Solution {
public:
    int nextGreaterElement(int n) {
        int a[11], len = 0;
        while (n > 0) {
            a[++len] = n % 10;
            n /= 10;
        }
        a[0] = INT_MIN;
        int ok = 0;
        for (int i = 1; i <= len; ++i) {
            if (a[i] < a[i-1]) {
                int idx = upper_bound(a+1, a+i, a[i]) - a;
                swap(a[idx], a[i]);
                for (int j = 1; j <= (i-1)/2; ++j) {
                    swap(a[j], a[i-j]);
                }
                ok = 1;
                break;
            }
        }
        if (!ok) return -1;
        long res = 0;
        for (int i = len; i > 0; --i) {
            res = res * 10 + a[i];
        }
        return res > INT_MAX ? -1 : res;
    }
};

python

class Solution:
    def nextGreaterElement(self, n: int) -> int:
        s = str(n)
        n = len(s)
        res = ''
        for i in range(n-1, -1, -1):
            res = s[i] + res
            if i < n-1 and res[0] < res[1]:
                res = ''.join(sorted(res))
                for j in range(n-i):
                    if res[j] > s[i]:
                        res = res[j] + res[:j] + res[j+1:]
                        break
                s = s[:i] + res
                return int(s) if int(s) < pow(2, 31) else -1
        return -1

后记

这题还可以直接用 c++ 标准库函数 next_permutation 直接生成下一个更大的字符串排列,然后转换成整数就行了,代码如下:

class Solution {
public:
    int nextGreaterElement(int n) {
        string s = to_string(n);
        next_permutation(s.begin(), s.end());
        long res = stoll(s);
        return res > INT_MAX || res <= n ? -1 : res;
    }
};
相关文章
|
1月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
36 1
|
1月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
44 3
|
1月前
【LeetCode 27】347.前k个高频元素
【LeetCode 27】347.前k个高频元素
33 0
|
1月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
38 0
|
16天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
1月前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
35 4
|
1月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
27 2
|
1月前
【LeetCode 06】203.移除链表元素
【LeetCode 06】203.移除链表元素
30 0
|
1月前
【LeetCode-每日一题】移除元素
【LeetCode-每日一题】移除元素
32 0
|
3月前
|
算法
测试工程师的技能升级:LeetCode算法挑战与职业成长
这篇文章通过作者亲身体验LeetCode算法题的过程,探讨了测试工程师学习算法的重要性,并强调了算法技能对于测试职业成长的必要性。
70 1
测试工程师的技能升级:LeetCode算法挑战与职业成长
下一篇
无影云桌面