496. Next Greater Element I(寻找下一个较大的数)

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.

题目大意:给定两个整型数组,nums1是nums2的子数组,nums1和nums2中都没有重复的元素。对nums1中的每个数,寻找它在nums2中对应数字的右边的第一个比它大的数,如果不存在则为-1,将结果存放在一个数组中返回。


解题思路:

解法一:暴力解法,遍历nums1,对其中的每个数,在nums2中找到该数,然后在nums2中该数的右边找第一个较大的数。

代码如下:(13ms,beats 37.66%)

public int[] nextGreaterElement(int[] findNums, int[] nums) {
		int findLen = findNums.length;
		int numsLen = nums.length;
		int i, j, k;
		int[] res = new int[findLen];
		for (i = 0; i < findLen; i++) {
			for (j = 0; j < numsLen; j++) {
				if (findNums[i] == nums[j]) {
					for (k = j + 1; k < numsLen; k++) {
						if (nums[k] > findNums[i]) {
							res[i] = nums[k];
							break;
						}
					}
					if (k == numsLen)
						res[i] = -1;
					break;
				}
			}
		}
		return res;
	}


解法二:首先确定nums2中每一个数和右边第一个较大数的关系。方法为维护一个栈和一个map,从尾到头遍历nums2,对于每一个数,如果栈顶元素小于该数,则栈顶元素出栈,直到找到大于该数的栈顶元素,此时将<该数,栈顶元素>放入map中,然后将该数也入栈;如果栈空了,则将<该数,-1>放入map中,同样将该数入栈。确定好这样一个关系后,就可以直接遍历nums1,对每一个元素直接在map中执行get,就可以确定nums2中下一个较大元素的值了。

代码如下:(14ms,beats 31.75%,没想到比暴力解法还慢- -)

public int[] nextGreaterElement(int[] findNums, int[] nums) {
        int findLen = findNums.length;
		int numsLen = nums.length;
		int[] res = new int[findLen];
		if (findLen == 0 || numsLen == 0 || findLen > numsLen)
			return res;
		Map<Integer, Integer> map = new HashMap<>();
		int[] stack = new int[numsLen];
		int index = -1;
		int i, j;
		int curMax = nums[numsLen - 1];
		map.put(curMax, -1);
		for (i = numsLen - 1; i >= 0; i--) {
			while (index >= 0) {
				if (nums[i] > stack[index])
					--index;
				else {
					map.put(nums[i], stack[index]);
					stack[++index] = nums[i];
					break;
				}
			}
			if (index < 0) {
				map.put(nums[i], -1);
				stack[++index] = nums[i];
			}
		}
		for (j = 0; j < findLen; j++) {
			res[j] = map.get(findNums[j]);
		}
		return res;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值