[LeetCode] 556. Next Greater Element III 下一个较大的元素 III
Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly the same digits existing in the integer nand is greater in value than n. If no such positive 32-bit integer exists, you need to return -1.
Example 1:
Input: 12 Output: 21
Example 2:
Input: 21 Output: -1
给一个32字节的正整数,找出由同样数位组成比给定数大的数字中最小的,其实就是对各个数位重新排序,求出刚好比给定数字大的一种排序,如果不存在就返回-1。
Java:
public class Solution { public int nextGreaterElement(int n) { char[] number = (n + "").toCharArray(); int i, j; // I) Start from the right most digit and // find the first digit that is // smaller than the digit next to it. for (i = number.length-1; i > 0; i--) if (number[i-1] < number[i]) break; // If no such digit is found, its the edge case 1. if (i == 0) return -1; // II) Find the smallest digit on right side of (i-1)'th // digit that is greater than number[i-1] int x = number[i-1], smallest = i; for (j = i+1; j < number.length; j++) if (number[j] > x && number[j] <= number[smallest]) smallest = j; // III) Swap the above found smallest digit with // number[i-1] char temp = number[i-1]; number[i-1] = number[smallest]; number[smallest] = temp; // IV) Sort the digits after (i-1) in ascending order Arrays.sort(number, i, number.length); long val = Long.parseLong(new String(number)); return (val <= Integer.MAX_VALUE) ? (int) val : -1; } }
Java:
class Solution { public int nextGreaterElement(int n) { // The same as : leetcode 31 Next Permutation, O(n) char[] number = (n + "").toCharArray(); int i = -1; //1. find backwards for(i = number.length - 1; i > 0; i--) if(number[i - 1] < number[i]) break; if(i == 0) return -1; //2. first, second int first = i - 1, second = i; //3. find the next greater than first, backward for(i = number.length - 1; i > first; i--) { if(number[i] > number[first]) { char temp = number[i]; number[i] = number[first]; number[first] = temp; break; } } //4. reverse after second reverse(number, second); //5. Transform back long val = Long.parseLong(new String(number)); return (val <= Integer.MAX_VALUE) ? (int) val : -1; } private void reverse(char[] a,int i)//reverse the number after the number we have found { int first = i; int last = a.length-1; while(first<last) { char t = a[first]; a[first] = a[last]; a[last] = t; first ++; last --; } } }
Python:
# Time: O(logn) = O(1) # Space: O(logn) = O(1) class Solution(object): def nextGreaterElement(self, n): """ :type n: int :rtype: int """ digits = map(int, list(str(n))) k, l = -1, 0 for i in xrange(len(digits) - 1): if digits[i] < digits[i + 1]: k = i if k == -1: digits.reverse() return -1 for i in xrange(k + 1, len(digits)): if digits[i] > digits[k]: l = i digits[k], digits[l] = digits[l], digits[k] digits[k + 1:] = digits[:k:-1] result = int("".join(map(str, digits))) return -1 if result >= 0x7FFFFFFF else result
C++:
class Solution { public: int nextGreaterElement(int n) { string str = to_string(n); int len = str.size(), i = len - 1; for (; i > 0; --i) { if (str[i] > str[i - 1]) break; } if (i == 0) return -1; for (int j = len - 1; j >= i; --j) { if (str[j] > str[i - 1]) { swap(str[j], str[i - 1]); break; } } sort(str.begin() + i, str.end()); long long res = stoll(str); return res > INT_MAX ? -1 : res; } };
C++:
/** * 1. a max number has the property of decreasing in every digit: 9876 * 2. find the first non-max substring from the right; ex. in 1234(59876), 59876 is the first non-max substring from the right * 3. sort the max part of 5(9876), by reverse, becames 5(6789); * 4. flip 5,6, becames 65789; because 6 is the next smallest digit than 5, in 56789; * 5. incase of 66789, you got flip 6 with 7 to make it 76689, to make it bigger. */ class Solution { public: int nextGreaterElement(int n) { string s = to_string(n); if (s.length() == 1) { return -1; } /* find the first decreasing digit from the right, eg: 59876, 5 is the first decreasing digit */ int i = s.length() - 2; // 21 -> i = 0; 59876 -> i = 3 for (; i >= 0 && s[i] >= s[i + 1]; i--) { } if (i == -1) { // if a decreasing digit cannot be find, the number cannot be larger. return -1; } reverse(s.begin() + i + 1, s.end()); for (int j = i + 1; j < s.length(); j++) { if (s[j] > s[i]) { swap(s[i], s[j]); break; } } long next = stol(s); return next == n || next > INT_MAX ? -1 : next; } };
C++: using next permutation
int nextGreaterElement(int n) { auto digits = to_string(n); next_permutation(begin(digits), end(digits)); auto res = stoll(digits); return (res > INT_MAX || res <= n) ? -1 : res; }
类似题目:
[LeetCode] 496. Next Greater Element I 下一个较大的元素 I
[LeetCode] 503. Next Greater Element II 下一个较大的元素 II
All LeetCode Questions List 题目汇总