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

  • 相关阅读:
    Luogu P2016 战略游戏(树形DP)
    Luogu P2486 染色(树链剖分+线段树)
    Luogu P3178 树上操作(树链剖分+线段树)
    Luogu P2590 树的统计(树链剖分+线段树)
    Luogu P2146 软件包管理器(树链剖分+线段树)
    获得spring
    网卡绑定多个ip
    描述01-配置文件咋整
    进程查看
    端口查看,进程杀死
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9854173.html
Copyright © 2020-2023  润新知