[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 题目汇总

 

posted @ 2018-10-26 03:41  轻风舞动  阅读(403)  评论(0编辑  收藏  举报