栈---下一个更大元素

  1. 题目
    给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。
    nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出-1。
  2. 示例
输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
    对于num1中的数字4,你无法在第二个数组中找到下一个更大的数字,因此输出 -1。
    对于num1中的数字1,第二个数组中数字1右边的下一个较大数字是 3。
    对于num1中的数字2,第二个数组中没有下一个更大的数字,因此输出 -1。
输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
    对于num1中的数字2,第二个数组中的下一个较大数字是3。
    对于num1中的数字4,第二个数组中没有下一个更大的数字,因此输出 -1。
  1. 注意

    nums1和nums2中所有元素是唯一的。
    nums1和nums2 的数组大小都不超过1000。

  2. 实现代码
    方法一 枚举
    a. 找nums1中的元素在nums2中对应元素的下标 k;
    b. 从下标k往后寻找第一个比num1中元素大的值。

public class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int []temp = new int[nums1.length];
        for(int i=0;i<nums1.length;i++){
            for(int j=0;j<nums2.length;j++){
                //找到元素nums1[i]在nums2中对应位置j
                if(nums1[i]==nums2[j]){
                    //从位置j开始往后遍历找比第一个比元素nums1[i]大的元素
                    int k = j;
                    for(;k<nums2.length;k++){
                        if(nums1[i]<nums2[k]){
                            //将第一个比nums1[i]大的元素记录到temp数组中
                            temp[i]=nums2[k];
                            //找到退出循环
                            break;
                        }
                    }
                    //不存在比nums1[i]大的元素,使temp[i]=-1
                    if(k==nums2.length){
                        temp[i]=-1;
                    }
                    //nums1为nums2的子集,肯定能在nums2中找到nums1中相同的元素
                    // 不需要考虑不存在相同元素的情况,退出循环即可
                    break;
                }
            }
        }
        return temp;
    }
}

方法二 Map实现
a. 构造Map,遍历nums1,key存在num1的元素值,value存放nums1中元素在nums2中对应的下标;
b. 遍历nums1,从map中获取该元素在num2中的下标,然后往后寻找比它大的元素。

 public int[] nextGreaterElement(int[] nums1, int[] nums2) {
      int temp[] = new int[nums1.length];
      Map<Integer,Integer> map =new HashMap<>();
      for(int i=0;i<nums1.length;i++){
          for(int j=0;j<nums2.length;j++){
              if(nums1[i]==nums2[j]){
                  //键存放nums1[i]元素,值存放nums1[i]元素在nums2中的下标
                  map.put(nums1[i],j);
                  break;
              }
          }
      }
      //遍历nums1,从map中获取该元素在num2中的下标,然后往后寻找比它大的元素
      for(int i=0;i<nums1.length;i++){
          //获取num1[i]在nums2中下标
          int j=map.get(nums1[i]);
          //往后寻找比nums[i]大的元素
          for(;j<nums2.length;j++){
              if(nums1[i]<nums2[j]){
                  temp[i]=nums2[j];
                  break;
              }
          }
          if(j==nums2.length){
              temp[i]=-1;
          }
      }
      return temp;
    }

方法三 Map实现
a.构造Map,遍历nums2,key存放nums2中元素的值,value为nums2中元素的下标;
b. 遍历nums1,从map中获取该元素在num2中的下标,然后往后寻找比它大的元素。

     public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int temp[] = new int[nums1.length];
        Map<Integer, Integer> map = new HashMap<>();
        for (int j = 0; j < nums2.length; j++) {
            //键为nums2[j]元素的值,值为该元素对应的下标
            map.put(nums2[j], j);
        }
        //遍历nums1,获取该元素在nums2中的下标,然后往后寻找比它大的元素
        for (int i = 0; i < nums1.length; i++) {
            //获取nums[i]在nums2中的下标
            int j = map.get(nums1[i]);
            //往后寻找比nums[i]大的元素
            for (; j < nums2.length; j++) {
                if (nums1[i] < nums2[j]) {
                    temp[i] = nums2[j];
                    break;
                }
            }
            if (j == nums2.length) {
                temp[i] = -1;
            }
        }
        return temp;
    }

方法四 栈+Map实现
数据结构
栈:用栈来维护一个栈顶元素最小的递增序列。里面存储的是还未找到比自己大的元素,初始时只包含第一个元素。
Map:key存放自身的值,value存放比自己大的值。
a.构造Map,遍历nums2,key存放nums2中元素的值,value存放nums2右边元素首个比该元素大的值。(若不存在比自己大的情况,不会存储到map中);
b.遍历nums1,查找map中是否存在nums1元素对应的key,若存在map中的value即为所求;不存在=-1。

 public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int[] temp = new int[nums1.length];
        //用栈来维护栈顶元素最小的序列
        Stack<Integer> stack = new Stack<>();
        Map<Integer,Integer> map = new HashMap<>();
        int top,next;
        //找到nums2中每个元素右边比自己大的数,存放到map中,key存放自身的值,value存放num2中第一个比自己大的值
        for(int i=0;i<nums2.length-1;i++){
            //上一个循环的next入栈
            stack.push(nums2[i]);
            top = stack.peek();
            next = nums2[i+1];
            //从栈顶top开始和next比较,如果top<next,表示找到了首个比top大的数,弹出栈,并存放到map中;
            //直到栈顶为空或next<=top.即next目前来说是最小的元素,可以入栈。
            while (!stack.empty()&&top<next){
                //键为栈顶元素的值,值为num2中右边首个比该值大的元素的值
                map.put(top,next);
                stack.pop();
                if(!stack.empty()){
                    //继续取栈顶元素比较
                    top = stack.peek();
                }
            }
        }
        //遍历num1,以num1中的值为键找map中相应的值
        for (int i=0;i<nums1.length;i++){
            //判断map的key中是否包含nums[i],不包含表示未找到比nums[i]中更大的元素
            if(map.containsKey(nums1[i])){
                temp[i] = map.get(nums1[i]);
            }else{
                temp[i]=-1;
            }
        }
        return temp;

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值