leetcode链接:
496. 下一个更大元素 I
题目分析



方案一
先重点关注 nums2,根据nums2的数值先求出其每位数值对应的下一个最大元素,因为其数值唯一,所以可以使用哈希表来存储其对应关系,这样对于nums1就简单了,只要对其进行遍历即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { int[] num2Tem = new int[nums2.length]; Deque<Integer> stack = new ArrayDeque<>(); Arrays.fill(num2Tem, -1); for (int i = 0; i < nums2.length; i++) { while (!stack.isEmpty() && nums2[stack.peek()] < nums2[i]) { Integer pop = stack.pop(); num2Tem[pop] = i; } stack.push(i); }
HashMap<Integer, Integer> hashMap = new HashMap<>(); for (int i = 0; i < num2Tem.length; i++) { if (num2Tem[i] == -1) { hashMap.put(nums2[i], -1); } else { hashMap.put(nums2[i], nums2[num2Tem[i]]); } }
int[] result = new int[nums1.length]; for (int i = 0; i < nums1.length; i++) { result[i] = hashMap.get(nums1[i]); }
return result; } }
|
结果
解答成功:
执行耗时:3 ms,击败了90.15% 的Java用户
内存消耗:42.5 MB,击败了33.75% 的Java用户
分析
时间复杂度:
O( 2m + n ) –> n为nums1的长度,m为nums2的长度
空间复杂度:
O( 2m + n )
代码随想录
https://programmercarl.com/0496.%E4%B8%8B%E4%B8%80%E4%B8%AA%E6%9B%B4%E5%A4%A7%E5%85%83%E7%B4%A0I.html
以下内容均搬上方链接的相关内容,具体请查看原网站: https://programmercarl.com/0496.%E4%B8%8B%E4%B8%80%E4%B8%AA%E6%9B%B4%E5%A4%A7%E5%85%83%E7%B4%A0I.html
几乎是一样的,但是这么绕了一下,其实还上升了一点难度。
需要对单调栈使用的更熟练一些,才能顺利的把本题写出来。
从题目示例中我们可以看出最后是要求nums1的每个元素在nums2中下一个比当前元素大的元素,那么就要定义一个和nums1一样大小的数组result来存放结果。
一些同学可能看到两个数组都已经懵了,不知道要定一个一个多大的result数组来存放结果了。
这么定义这个result数组初始化应该为多少呢?
题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。
在遍历nums2的过程中,我们要判断nums2[i]是否在nums1中出现过,因为最后是要根据nums1元素的下标来更新result数组。
注意题目中说是两个没有重复元素 的数组 nums1 和 nums2。
没有重复元素,我们就可以用map来做映射了。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过。
使用单调栈,首先要想单调栈是从大到小还是从小到大。
本题和739. 每日温度是一样的。
栈头到栈底的顺序,要从小到大,也就是保持栈里的元素为递增顺序。只要保持递增,才能找到右边第一个比自己大的元素。
可能这里有一些同学不理解,那么可以自己尝试一下用递减栈,能不能求出来。其实递减栈就是求右边第一个比自己小的元素了。
接下来就要分析如下三种情况,一定要分析清楚。
情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
此时满足递增栈(栈头到栈底的顺序),所以直接入栈。
情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
如果相等的话,依然直接入栈,因为我们要求的是右边第一个比自己大的元素,而不是大于等于!
情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。
判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的元素),如果出现过,开始记录结果。
记录结果这块逻辑有一点小绕,要清楚,此时栈顶元素在nums2数组中右面第一个大的元素是nums2[i](即当前遍历元素)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Stack<Integer> temp = new Stack<>(); int[] res = new int[nums1.length]; Arrays.fill(res,-1); HashMap<Integer, Integer> hashMap = new HashMap<>(); for (int i = 0 ; i< nums1.length ; i++){ hashMap.put(nums1[i],i); } temp.add(0); for (int i = 1; i < nums2.length; i++) { if (nums2[i] <= nums2[temp.peek()]) { temp.add(i); } else { while (!temp.isEmpty() && nums2[temp.peek()] < nums2[i]) { if (hashMap.containsKey(nums2[temp.peek()])){ Integer index = hashMap.get(nums2[temp.peek()]); res[index] = nums2[i]; } temp.pop(); } temp.add(i); } }
return res; } }
class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { HashMap<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums1.length; i++) { map.put(nums1[i], i); }
int[] res = new int[nums1.length]; Stack<Integer> stack = new Stack<>(); Arrays.fill(res, -1);
for (int i = 0; i < nums2.length; i++) { while (!stack.isEmpty() && nums2[stack.peek()] < nums2[i]) { int pre = nums2[stack.pop()]; if (map.containsKey(pre)) { res[map.get(pre)] = nums2[i]; } } stack.push(i); }
return res; } }
|
官方题解
https://leetcode.cn/problems/next-greater-element-i/solution/xia-yi-ge-geng-da-yuan-su-i-by-leetcode-bfcoj/

具体例子请见: https://leetcode.cn/problems/next-greater-element-i/solution/xia-yi-ge-geng-da-yuan-su-i-by-leetcode-bfcoj/

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Map<Integer, Integer> map = new HashMap<Integer, Integer>(); Deque<Integer> stack = new ArrayDeque<Integer>(); for (int i = nums2.length - 1; i >= 0; --i) { int num = nums2[i]; while (!stack.isEmpty() && num >= stack.peek()) { stack.pop(); } map.put(num, stack.isEmpty() ? -1 : stack.peek()); stack.push(num); } int[] res = new int[nums1.length]; for (int i = 0; i < nums1.length; ++i) { res[i] = map.get(nums1[i]); } return res; } }
作者:LeetCode-Solution 链接:https: 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
|
