739. 每日温度
力扣题目链接
请根据每日气温列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温列表长度的范围是 [1, 30000]。每个气温的值均为华氏度,都是在 [30, 100] 范围内的整数。
解题思路
我们可以使用一个栈来帮助我们解决这个问题。栈中存储的是气温列表中元素的索引,而不是气温值本身。我们从左到右遍历气温列表,对于每个元素,我们检查栈顶元素所对应的气温是否小于当前气温。如果是,那么我们就可以计算出需要等待的天数,并更新结果数组。我们将当前元素的索引压入栈中,以便后续元素可以使用它来计算等待天数。
以下是具体的步骤:
- 初始化一个结果数组
result,长度与气温列表相同,初始值均为 0。 - 使用一个栈
stack来存储气温列表的索引。 - 遍历气温列表,对于每个元素:
- 当栈不为空,且栈顶元素对应的气温小于当前气温时,弹出栈顶元素,并计算等待天数,更新结果数组。
- 将当前元素的索引压入栈中。
- 遍历结束后,栈中剩余的索引对应的结果数组位置都是 0,因为之后不会有更高的气温。
以下是具体的代码实现:
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int[] result = new int[temperatures.length];
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
for (int i = 1; i < temperatures.length; i++) {
while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) {
int index = stack.pop();
result[index] = i - index;
}
stack.push(i);
}
return result;
}
}
这个算法的时间复杂度是 O(N),因为每个元素最多只会被压入和弹出栈一次。空间复杂度也是 O(N),因为我们需要一个额外的数组来存储结果,以及一个栈来存储索引。
496. 下一个更大元素 I
力扣题目链接
给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中 nums1 是 nums2 的子集。
请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。
解题思路
我们可以使用单调栈来解决这个问题。单调栈是一种特殊的栈,用于解决一类特定的问题,即找到下一个更大元素、下一个更小元素等。
以下是解题步骤:
- 创建一个结果数组
result,初始化所有值为-1,因为如果找不到更大的元素,则返回-1。 - 使用一个哈希表
hashMap来存储nums1中每个元素的位置,以便我们可以快速更新result数组。 - 初始化一个栈
stack,用于存储nums2中元素的索引。 - 遍历
nums2,对于每个元素,如果当前元素大于栈顶元素对应的nums2中的值,那么我们就找到了栈顶元素在nums2中的下一个更大元素。我们将这个更大元素赋值给result数组中对应nums1的位置,并弹出栈顶元素。 - 如果当前元素不大于栈顶元素,则将其索引压入栈中。
- 继续遍历,直到
nums2的所有元素都被处理。
以下是具体的代码实现:
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int[] result = new int[nums1.length];
Arrays.fill(result, -1); // 初始化结果数组
Deque<Integer> stack = new LinkedList<>(); // 初始化栈
HashMap<Integer, Integer> hashMap = new HashMap<>(); // 初始化哈希表
for (int i = 0; i < nums1.length; i++) {
hashMap.put(nums1[i], i); // 存储nums1中元素的位置
}
stack.push(0); // 将nums2的第一个元素的索引压入栈中
for (int i = 1; i < nums2.length; i++) {
while (!stack.isEmpty() && nums2[stack.peek()] < nums2[i]) {
if (hashMap.containsKey(nums2[stack.peek()])) {
Integer index = hashMap.get(nums2[stack.peek()]);
result[index] = nums2[i]; // 更新结果数组
}
stack.pop(); // 弹出栈顶元素
}
stack.push(i); // 将当前元素的索引压入栈中
}
return result;
}
}
这个算法的时间复杂度是 O(M+N),其中 M 是 nums1 的长度,N 是 nums2 的长度。因为每个元素最多只会被压入和弹出栈一次。空间复杂度是 O(N),因为我们需要一个额外的数组来存储结果,以及一个栈和一个哈希表来存储索引和映射关系。
503. 下一个更大元素 II
力扣题目链接
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
解题思路
由于数组是循环的,我们可以通过将数组长度翻倍来模拟循环的效果。这样,我们可以使用单调栈来找到每个元素的下一个更大元素。
以下是解题步骤:
- 初始化一个结果数组
result,长度与输入数组nums相同,并将所有元素设置为 -1,因为如果找不到更大的元素,则返回 -1。 - 使用一个双端队列
stack来作为栈,用于存储元素的索引。 - 遍历数组,由于是循环数组,我们将遍历的次数设置为
nums.length * 2,通过取余操作i % nums.length来模拟循环。 - 对于每个元素,如果当前元素大于栈顶元素对应的
nums中的值,那么我们就找到了栈顶元素在nums中的下一个更大元素。我们将这个更大元素赋值给result数组中对应的位置,并将栈顶元素弹出。 - 将当前元素的索引压入栈中。
- 最后返回
result数组。
代码实现
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] result = new int[nums.length];
Arrays.fill(result, -1);
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
for (int i = 1; i < nums.length * 2; i++) {
while (!stack.isEmpty() && nums[stack.peek()] < nums[i % nums.length]) {
int index = stack.pop();
result[index] = nums[i % nums.length];
}
stack.push(i % nums.length);
}
return result;
}
}
这个算法的时间复杂度是 O(N),因为尽管我们遍历了两次数组,但每个元素最多只会被压入和弹出栈一次。空间复杂度是 O(N),因为我们需要一个额外的数组来存储结果,以及一个栈来存储索引。
1484

被折叠的 条评论
为什么被折叠?



