739. 每日温度
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例 1: 输入: temperatures = [73,74,75,71,69,72,76,73] 输出: [1,1,4,2,1,1,0,0] 示例 2: 输入: temperatures = [30,40,50,60] 输出: [1,1,1,0] 示例 3: 输入: temperatures = [30,60,90] 输出: [1,1,0]
思路
单调栈的核心思想是:维护一个栈,使得栈中的元素保持单调递增或递减。在这个问题中,我们希望找到下一个更高的温度,因此我们需要维护一个单调递减栈,栈中存储的是数组下标,而非温度值。 对于每一天,我们将当前天的温度与栈顶索引对应的温度进行比较:
- 如果当前天的温度更高,那么我们就找到了栈顶天数之后的一个更高温度。我们将栈顶元素弹出,并计算两个索引之间的差距,这就是答案数组中对应的值。
- 如果当前天的温度不高于栈顶索引对应的温度,我们将当前索引压入栈中。
题解
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> answer(n, 0); // 初始化结果数组,初始值为0
stack<int> tempStack; // 维护一个单调递减栈,存储索引
for (int i = 0; i < n; i++) {
// 当前温度与栈顶索引对应温度比较
while (!tempStack.empty() && temperatures[i] > temperatures[tempStack.top()]) {
int prevIndex = tempStack.top();
tempStack.pop();
answer[prevIndex] = i - prevIndex; // 计算索引差距
}
tempStack.push(i); // 将当前索引压栈
}
return answer;
}
};
496. 下一个更大元素 I
nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。
给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。
对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。
示例 1:
输入:nums1 = [4,1,2], nums2 = [1,3,4,2]. 输出:[-1,3,-1] 解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。 示例 2:
输入:nums1 = [2,4], nums2 = [1,2,3,4]. 输出:[3,-1] 解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。
提示:
1 <= nums1.length <= nums2.length <= 1000 0 <= nums1[i], nums2[i] <= 10^4 nums1和nums2中所有整数 互不相同 nums1 中的所有整数同样出现在 nums2 中
思路
利用一个哈希表和一个单调栈。首先,遍历 nums2,利用单调栈找出每个元素右边第一个更大的元素,并将这个映射关系存储在哈希表中。之后可以直接遍历 nums1,根据哈希表找出每个元素的下一个更大元素。
- 初始化一个栈
stack以及一个哈希表unordered_map<int, int> nextGreater,用于存放nums2中每个元素对应的下一个更大元素的映射关系。 - 遍历
nums2:
- 对于当前元素
nums2[i],当栈不为空且栈顶元素小于nums2[i]时,说明栈顶元素的下一个更大元素是nums2[i]。将这个关系存入哈希表,并弹出栈顶元素。 - 将
nums2[i]压入栈中。
- 遍历完成后,栈中剩余元素在
nums2中没有下一个更大元素,可以在哈希表中将它们对应的值设为-1。 - 初始化结果数组
vector<int> ans(nums1.size(), -1),默认所有元素的下一个更大元素为-1。 - 遍历
nums1:
- 对于每个元素
nums1[i],查找哈希表nextGreater中是否有这个元素的下一个更大元素,如果有,更新结果数组ans[i]。
题解
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
stack<int> s;
unordered_map<int, int> nextGreater;
for (int num : nums2) {
while (!s.empty() && s.top() < num) {
nextGreater[s.top()] = num;
s.pop();
}
s.push(num);
}
// 对于栈中剩余的元素,它们没有下一个更大的元素
while (!s.empty()) {
nextGreater[s.top()] = -1;
s.pop();
}
vector<int> ans(nums1.size());
for (int i = 0; i < nums1.size(); ++i) {
ans[i] = nextGreater[nums1[i]];
}
return ans;
}
};