小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
下一个更大的数I
该题出自力扣496题——下一个更大的数I(简单题),题解是自己做的
审题
给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存
在,对应位置输出 -1 。
-
首先,给出两个数组,数组1是数组2的子集,也就是需要找出数组1 在数组2相应位置的下一个大的数
-
(√)方法一:暴力循环
- 需要两个for循环,外层数组1,里层数组2
- 其次,需要记录下数组1元素在数组2里面相应的下标位置
- 判断当数组2元素 > 数组1元素时 && 数组2下标要 > 数组2相应数组1元素的下标
- 时间复杂度O(m * n),空间复杂度O(1)
-
(√)方法二:单向栈+哈希表
- 利用栈的原理(先入后出) + 哈希表存储相应的下标+值
- 从最右遍历数组2,判断栈内元素是否 > 当前元素,是则不断弹出栈内元素直到有> 的元素再添进去
- 哈希表存储当前元素为下标,value存储栈顶首个元素,如果为空就代表没有更大的,填-1
- 最后遍历数组1,获取map下标元素即可
- 时间复杂度O(m+n),空间复杂度O(n)——哈希存储
编码
public static int[] nextGreaterElement1(int[] nums1, int[] nums2) {
/*利用单向栈实现
从最右开始遍历,实现从大到小的顺序,如果存在更大的,则不断弹出直到顺序,并且用一个map去存储相应的下标
*/
Map<Integer,Integer> map = new HashMap<>(nums2.length);
Deque<Integer> deque = new ArrayDeque<>();
for (int i = nums2.length -1; i>=0;i--){
int num = nums2[i];
while (!deque.isEmpty() && num > deque.peek()){
deque.poll();
}
map.put(num,deque.isEmpty()?-1:deque.peek());
deque.push(num);
}
int[] c = new int[nums1.length];
for (int i = 0;i<nums1.length;i++){
c[i] = map.get(nums1[i]);
}
return c;
}