[LeetCode] 556. Next Greater Element III

Given a positive integer n, find the smallest integer which has exactly the same digits existing in the integer n and is greater in value than n. If no such positive integer exists, return -1.

Note that the returned integer should fit in 32-bit integer, if there is a valid answer but it does not fit in 32-bit integer, return -1.

Example 1:

Input: n = 12
Output: 21

Example 2:

Input: n = 21
Output: -1

Constraints:

  • 1 <= n <= 231 - 1

下一个更大的元素III。

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

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/next-greater-element-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

版本三其实跟前两个版本几乎没什么关系,是一道找 next permutation 的题,思路同31题一模一样。题意是给一个整数,请找出 Integer 范围内用到相同数字但是比当前数字大的数字。如果想看怎么跑例子可以参见我31题的题解。题干中给的例子不是很好,我这里给一个更长的例子。

198765432, 他的下一个更大的元素是213456789

首先排除一个 corner case,如果 input 的 digits 是从左到右递减的,比如 54321 这种,他是没有更大的元素的,直接返回 -1。那么一般的 case 是什么呢,比如 198765432,他的下一个更大的元素是通过把最后一位的2先跟1交换,得到 298765431,然后再把红色的部分整体 reverse 得到 213456789。为什么是 1 跟 2 交换是因为 1 之后的数字突然就大了,而且 2 是右侧比 1 大的数字里面最小的那一个。

所以在写代码的时候,交换的原则是数字从右往左扫描,一般情况下会一直递增,当突然发现一个数字不再递增的时候就停下。停下的位置上的数字要跟数字最后一位交换,比如这个例子里的1和2,198765432。交换完了之后,因为1之后的部分都是递减的,所以需要整体翻转,以得到最后的那个数字。

时间O(n)

空间O(1) - 因为创建的数组最多只有32位,并不随着input变大

Java实现

 1 class Solution {
 2     public int nextGreaterElement(int n) {
 3         String number = String.valueOf(n);
 4         char[] nums = number.toCharArray();
 5         int i = nums.length - 2;
 6         while (i >= 0 && nums[i] >= nums[i + 1]) {
 7             i--;
 8         }
 9         if (i < 0)
10             return -1;
11 
12         int j = nums.length - 1;
13         while (j >= 0 && nums[j] <= nums[i]) {
14             j--;
15         }
16         swap(nums, i, j);
17         reverse(nums, i + 1);
18         long val = Long.parseLong(new String(nums));
19         return val <= Integer.MAX_VALUE ? (int) val : -1;
20     }
21 
22     private void reverse(char[] chars, int start) {
23         int i = start;
24         int j = chars.length - 1;
25         while (i < j) {
26             swap(chars, i++, j--);
27         }
28     }
29 
30     private void swap(char[] chars, int i, int j) {
31         char temp = chars[i];
32         chars[i] = chars[j];
33         chars[j] = temp;
34     }
35 }

 

相关题目

31. Next Permutation

556. Next Greater Element III

LeetCode 题目总结

posted @ 2020-03-16 08:54  CNoodle  阅读(176)  评论(0编辑  收藏  举报