LeetCode.496(503、556) Next Greater Element I && II && III

来源:互联网 发布:linux less命令 编辑:程序博客网 时间:2024/06/08 15:12

题目496:

You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2

The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.

Example 1:

Input: nums1 = [4,1,2], nums2 = [1,3,4,2].Output: [-1,3,-1]Explanation:    For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.    For number 1 in the first array, the next greater number for it in the second array is 3.    For number 2 in the first array, there is no next greater number for it in the second array, so output -1.

Example 2:

Input: nums1 = [2,4], nums2 = [1,2,3,4].Output: [3,-1]Explanation:    For number 2 in the first array, the next greater number for it in the second array is 3.    For number 4 in the first array, there is no next greater number for it in the second array, so output -1.

Note:

  1. All elements in nums1 and nums2 are unique.
  2. The length of both nums1 and nums2 would not exceed 1000.
分析(原创):

class Solution {    public int[] nextGreaterElement(int[] nums1, int[] nums2) {         //给定两个数组,其中nums1是nums2的子集(无重复)。请分别找出nums1中的元素在nums2中后面比该元素大的第一个元素        //若在nums2中后面不存在这样的更大的元素,返回-1代替。        //思路:使用数组实现,将以nums2的元素为下标存入对应的位置                        int [] res=new int[nums1.length];        //初始化数组        Arrays.fill(res,-1);        //确定下标数组的范围        int maxNum=Integer.MIN_VALUE;        int minNum=Integer.MAX_VALUE;        for(int i=0;i<nums2.length;i++){            maxNum=Math.max(maxNum,nums2[i]);            minNum=Math.min(minNum,nums2[i]);        }        //创建对应的下标数组,为了方便直接从对应元素后面查找        int [] index=new int[maxNum-minNum+1];        for(int i=0;i<nums2.length;i++){            index[nums2[i]-minNum]=i;        }        //查找元素        for(int i=0;i<nums1.length;i++){            for(int j=index[nums1[i]-minNum];j<nums2.length;j++){                if(nums2[j]>nums1[i]){                    res[i]=nums2[j];                    break;                }            }        }        return res;            }}

题目503:

Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number.

Example 1:

Input: [1,2,1]Output: [2,-1,2]Explanation: The first 1's next greater number is 2; 
The number 2 can't find next greater number;
The second 1's next greater number needs to search circularly, which is also 2.

Note: The length of given array won't exceed 10000.

分析(原创-易理解):

class Solution {    public int[] nextGreaterElements(int[] nums) {        //类似Next Greater Element的原理,只是这里首尾是相连的,当判断末尾时,需要从头开始继续判断。        //直到找到满足条件位为止,否则返回-1。(注意:存在相同元素)        //思路:类似498的解法,求出每个元素的的下标,如果相同的元素,直接更新下标。            //Hint:每个元素寻找的长度为n-1(前面n-1个和后面n-i+1个),利用mod回到原点继续遍历        int [] res=new int[nums.length];        if(nums.length==0) return res;        Arrays.fill(res,-1);                //遍历查找        for(int i=0;i<nums.length;i++){            for(int j=i+1;j<nums.length+i;j++){                //求mod运算                if(nums[j%nums.length]>nums[i]){                    res[i]=nums[j%nums.length];                    break;                }            }        }                return res;                    }}

分析2(参考答案-推荐):

class Solution {    public int[] nextGreaterElements(int[] nums) {        //类似Next Greater Element的原理,只是这里首尾是相连的,当判断末尾时,需要从头开始继续判断。        //直到找到满足条件位为止,否则返回-1。(注意:存在相同元素)        //思路:类似498的解法,使用一个栈来记录,找到比前面元素n大的话,直至不满足的条件。就在数组中n下标的赋值比其大的数        //两轮比较,数组中的每个数都能找到比其大的。        int len=nums.length;        int [] next=new int[len];        Arrays.fill(next,-1);        Stack<Integer> stack = new Stack<>();        //轮询两次,来表示一个完整的环        for(int i=0;i<len*2;i++){            int num=nums[i%len];            //取栈定元素进行比较            while(!stack.empty()&&nums[stack.peek()]<num){                //找到比其大的,重新赋值                next[stack.pop()]=num;            }            if(i<len){                //将下标存入                stack.push(i);            }        }        return next;                   }}

题目556:

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: 12Output: 21

Example 2:

Input: 21Output: -1

分析556(原创):

class Solution {    public static int nextGreaterElement(int n) {        //给定一个正整数,你需要返回由其的数字组成的,且比其大的最小元素,若这样的数不存在,则返回-1        //思路:对该数字进行切分,将其各个位置的数放入一个数字,结合前面503和498的解法,来求解比其大的Next Great Element        //注意:不能使用枚举的方法将所有子集列出,必定TLM        //分三种情况:1:升序。则只需要将最后面两个数字交换即可//                  2:降序。则没有满足条件的,返回-1//                  3:不符合上述两者的无序情况(从右边开始查找第一个不满足比后面一个前面一个大的数,//                  之后将该数和它右边比其大的数交换,最后将后半段排序即可)        int temp=n;        int len=0;        while(temp>0){            temp/=10;            len++;        }        //创建数组        int [] res=new int[len];        int newTemp=n;        //将各个元素放入数组(正序放入)        while(newTemp>0){            res[--len]=newTemp%10;            newTemp/=10;        }                //判断所属情况        int i;        for(i=res.length-1;i>0;i--){            if(res[i]>res[i-1])                break;        }                if(i==0){            //说明为降序            return -1;        }                //找到恰好满足比当前位置大的数        int x=res[i-1],minIndex=i;        for(int j=i+1;j<res.length;j++){            if(res[j]>x&&res[j]<=res[minIndex]){                minIndex=j;            }        }        //交换位置        swap(res,i-1,minIndex);        //右半部分排序        Arrays.sort(res,i,res.length);        //转成结果        return transform(res)>Integer.MAX_VALUE?-1:(int)transform(res);            }    //交换数据    public static int[] swap(int [] nums,int n,int m){        int temp=nums[m];        nums[m]=nums[n];        nums[n] = temp;        return nums;    }    //将数组转成数字(Integer的范围)    public static long transform(int [] nums){        long sum=0;        for(int i=0;i<nums.length;i++){            sum=sum*10+nums[i];        }        return sum;    }}


原创粉丝点击