力扣496. 下一个更大元素 I
给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出-1。
思路:
创建一个临时栈,一个哈希表,然后遍历 nums2nums2。
若当前栈无数据,则当前数字入栈备用。
若当前栈有数据,则用当前数字与栈顶比较:
3.1 当前数字 > 栈顶,代表栈顶对应下一个更大的数字就是当前数字,则将该组数字对应关系,记录到哈希表。
3.2 当前数字 < 栈顶,当前数字压入栈,供后续数字判断使用。
这样,我们就可以看到哈希表中存在部分 nums2nums2 数字的对应关系了,而栈中留下的数字,代表无下一个更大的数字,我们全部赋值为 -1−1 ,然后存入哈希表即可。
遍历 nums1nums1,直接询问哈希表拿对应关系即可。
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
stack<int>s;
unordered_map<int,int>num_map;
int size = nums1.size();
vector<int>vec_num;
for(int i = 0;i < nums2.size();++i)
{
while(!s.empty() && nums2[i]>s.top())
{
num_map[s.top()] = nums2[i];
s.pop();
}
s.push(nums2[i]);
}
while(!s.empty())
{
num_map[s.top()] = -1;
s.pop();
}
for(int i = 0;i<size;++i)
{
vec_num.push_back(num_map[nums1[i]]);
}
return vec_num;
}
};
作者:demigodliu
链接:https://leetcode-cn.com/problems/next-greater-element-i/solution/zhan-xia-yi-ge-geng-da-yuan-su-i-by-demi-cumj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
力扣503. 下一个更大元素 II
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
思路:
讲两个nums数组拼接在一起,使用单调栈计算出每一个元素的下一个最大值,最后再把结果集即result数组resize到原数组大小就可以了。
// 版本二
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> result(nums.size(), -1);
if (nums.size() == 0) return result;
stack<int> st;
for (int i = 0; i < nums.size() * 2; i++) {
// 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
while (!st.empty() && nums[i % nums.size()] > nums[st.top()]) {
result[st.top()] = nums[i % nums.size()];
st.pop();
}
st.push(i % nums.size());
}
return result;
}
};
作者:carlsun-2
链接:https://leetcode-cn.com/problems/next-greater-element-ii/solution/503-xia-yi-ge-geng-da-yuan-su-iidan-diao-9ez5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
力扣456. 132 模式
给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。
如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。
思路:
枚举到 2:栈内元素为 [2],k = INF
枚举到 4:不满足「单调递减」,2 出栈更新 k,4 入栈。栈内元素为 [4],k = 2
枚举到 1:满足 nums[i] < k,说明对于 i 而言,后面有一个比其大的元素(满足 i < k 的条件),同时这个 k 的来源又是因为维护「单调递减」而弹出导致被更新的(满足 i 和 k 之间,有比 k 要大的元素)。因此我们找到了满足 132 结构的组合。
class Solution {
public:
bool find132pattern(vector<int>& nums) {
stack<int> st;
int n = nums.size(), k = INT_MIN;
for(int i = n - 1; i >= 0; i--){
if(nums[i] < k) return true;
while(!st.empty() and st.top() < nums[i]) {
k = max(k,st.top()); st.pop();
}
st.push(nums[i]);
}
return false;
}
};
作者:AC_OIer
链接:https://leetcode-cn.com/problems/132-pattern/solution/xiang-xin-ke-xue-xi-lie-xiang-jie-wei-he-95gt/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
力扣862. 和至少为 K 的最短子数组
返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。
如果没有和至少为 K 的非空子数组,返回 -1 。
思路:
一个双端单调队列:如果新加入的数比队列尾的数小,那么队列尾的数就可以丢去,这是因为如果未来的一个数能和队列尾的数满足条件,那么也一定可以和新加入的数满足条件。 另外,如果一个数和队列头的数已经满足了条件,那么队列头的数就不用保留了,这是因为以后加入的数,就算能和队列头的数满足条件,也会比现在的长度大。
class Solution {
public:
int shortestSubarray(vector<int>& A, int K) {
int n = A.size();
vector<long> sum(n+1, 0);
for(int i = 0; i < n; i++) //准备工作
sum[i+1] = sum[i] + A[i];
deque<int> de;
int j = 0;
int res = n+1;
while(j<=n){
while(!de.empty() && sum[j] <= sum[de.back()]){
de.pop_back();
}
while(!de.empty() && sum[j] - sum[de.front()] >= K){
res = min( res, j - de.front());
de.pop_front();
}
de.push_back(j); //最后才坐下去
j++;
}
if(res == n+1)
return -1;
else
return res;
}
};
作者:ka-pei-qing-jia-wu-shao-tang
链接:https://leetcode-cn.com/problems/shortest-subarray-with-sum-at-least-k/solution/he-guan-fang-yi-yang-de-jie-fa-zi-ji-de-yi-dian-di/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。