Next Greater Element

Problem 1:

given two array of numbers arr1, arr2. arr1 is the subset of arr2 and we assume that all element in each array are distinct. Find the next greater number of numbers in arr1 in terms of the sequence of arr2. 

Solution:

1. The key point is that in a decreasing sequence, if we find next number n is greater than the last one of this sequence, we know that for every element less than n in the decreasing sequence, the next greater number is n.

e.g. 6,3,2 -> then we find 4 -> we know that next greater number for 3 and 2 is 4.

2. Use a HashMap to store the result. Mapping relation: number -> next greater number. We use a stack to store the decreasing sequence.

3. Scan the whole arr2 and if stack is not empty and the top of the stack is less than current number. we pop the stack and put the mapping to the hashmap until the top of the stack is not less than current number or the stack is empty. Then push the current number into the stack.

4. for every number in arr1, if the map contains key of that number, we put the value of that key to current position of arr1 or we put -1 to that position.

Code:

public class Solution {
    public int[] nextGreaterElement(int[] findNums, int[] nums) {
        if(nums.length == 0)
            return new int[]{};
        Stack<Integer> st = new Stack<>();
        Map<Integer, Integer> greater = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            while(!st.isEmpty() && st.peek()<nums[i]){
                greater.put(st.pop(), nums[i]);
            }
            st.push(nums[i]);
        }
        for(int i = 0; i < findNums.length; i++){
            findNums[i] = greater.getOrDefault(findNums[i], -1);
        }
        return findNums;
    }
}
View Code

 

Problem 2:

Given an circulate array, which means that the next element of the tail of the array is the head of the array. Print next greater element for every number in the array.

e.g. 2, 4, 1 -> 4, -1, 2

Solution:

Similar to Problem 1, this time we scan the array for two times and during the second time we do not push any element to the stack. Also we use an array to store the result and the stack stores the index of each element so that we can put the greater number to the corresponding position of the result array.

Code:

public class Solution {
    public int[] nextGreaterElements(int[] nums) {
        if(nums.length == 0)
            return new int[]{};
        Stack<Integer> st = new Stack<Integer>();
        int[] result = new int[nums.length];
        Arrays.fill(result, -1);
        for(int i = 0; i < nums.length; i++){
            while(!st.isEmpty() && nums[st.peek()] < nums[i]){
                result[st.pop()] = nums[i];
            }
            st.push(i);
        }
        for(int i = 0; i < nums.length; i++){
            while(!st.isEmpty() && nums[st.peek()] < nums[i])
                result[st.pop()]=nums[i];
        }
        return result;
    }
}
View Code

 

Problem 3:

Given a positive integer, you need to find the number that contains the same digit as the integer and is greater than the integer. If there is no such number, return -1.

e.g. 12 -> 21;    21 -> -1

Solution:

1. This problem is similar to the "Next Permutation" problem, we can convert the number to a char array and find the next permutation of that char array. If the result is more than the Max Value of Integer, we just return -1.

2. For "Next Permutation" problem, we scan the array from the end and find the first number arr[i] that is smaller than  arr[i+1]. Then still from the end of the array, we find the fist number arr[j] that is more than arr[i]. Then we swap arr[i] and arr[j] and sort from arr[i+1] to the end of the array.

3. We use a long variable to store the ParseLong value of the new integer we get. return it or -1 if it's more than the Max value of Integer.

Code:

public class Solution {
    public int nextGreaterElement(int n) {
        String s = n+"";
        char[] arr = s.toCharArray();
        for(int i = arr.length-2; i >=0; i--){
            if(arr[i]<arr[i+1]){
                int j = i+1;
                for(; j<arr.length; j++){
                    if(arr[j]<=arr[i]){
                        j=j-1;
                        break;
                    }
                }
                if(j==arr.length)
                    j--;
                swap(arr, i, j);
                Arrays.sort(arr, i+1, arr.length);
                long temp = Long.parseLong(new String(arr));
                return (temp<=Integer.MAX_VALUE)? (int)temp : -1;
            }
        }
        return -1;
    }
    private void swap(char[] arr, int index1, int index2){
        arr[index1]^=arr[index2];
        arr[index2]^=arr[index1];
        arr[index1]^=arr[index2];
    }
}
View Code

 

posted @ 2017-06-23 05:03  小风约定  阅读(65)  评论(0)    收藏  举报