LeetCode Day60

49 阅读3分钟

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,根据哈希表找出每个元素的下一个更大元素。

  1. 初始化一个栈 stack 以及一个哈希表 unordered_map<int, int> nextGreater,用于存放 nums2 中每个元素对应的下一个更大元素的映射关系。
  2. 遍历 nums2
  • 对于当前元素 nums2[i],当栈不为空且栈顶元素小于 nums2[i] 时,说明栈顶元素的下一个更大元素是 nums2[i]。将这个关系存入哈希表,并弹出栈顶元素。
  • nums2[i] 压入栈中。
  1. 遍历完成后,栈中剩余元素在 nums2 中没有下一个更大元素,可以在哈希表中将它们对应的值设为 -1
  2. 初始化结果数组 vector<int> ans(nums1.size(), -1),默认所有元素的下一个更大元素为 -1
  3. 遍历 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;
    }
};