*739. 每日温度
单调栈。栈内存储访问过的元素下标,从栈顶到栈底保持单调递增。当前元素小于栈顶指向元素时,直接入栈;当前元素大于栈顶指向元素时,将所有指向元素小于当前元素的下标弹出同时计算该元素的结果,再将当前元素放入栈中。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
// c++
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int len = temperatures.size();
vector<int> result(len, 0);
stack<int> st;
st.push(0);
for(int i=1; i<len; i++){
if(temperatures[i]<=temperatures[st.top()]){
st.push(i);
}else{
while(!st.empty() && temperatures[i]>temperatures[st.top()]){
result[st.top()] = i-st.top();
st.pop();
}
st.push(i);
}
}
return result;
}
};
496. 下一个更大元素 I
本题和上题一样,使用单调栈。
解法一(暴力搜)
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
n
)
O(n)
O(n)
// c++
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> result(nums2.size(), -1);
vector<int> res(nums1.size(), -1);
stack<int> st;
st.push(0);
for(int i=1; i<nums2.size(); i++){
while(!st.empty() && nums2[i] > nums2[st.top()]){
result[st.top()] = i;
st.pop();
}
st.push(i);
}
for(int i=0; i<nums1.size(); i++){
for(int j=0; j<nums2.size(); j++){
if(nums1[i] == nums2[j]) {
if(result[j]!=-1)
res[i] = nums2[result[j]];
else
res[i] = -1;
break;
}
}
}
return res;
}
};
解法二(用map)
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
//c++
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> result(nums2.size(), -1);
vector<int> res(nums1.size(), -1);
unordered_map<int, int> umap;
for(int i=0; i<nums1.size(); i++) umap[nums1[i]] = i;
stack<int> st;
st.push(0);
for(int i=1; i<nums2.size(); i++){
while(!st.empty() && nums2[i] > nums2[st.top()]){
if(umap.count(nums2[st.top()])>0){
res[umap[nums2[st.top()]]] = nums2[i];
}
st.pop();
}
st.push(i);
}
return res;
}
};
503. 下一个更大元素 II
解法一(拼接两个数组)
把数组再复制一次拼接在原数组后实现循环数组
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
// c++
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int len = nums.size();
vector<int> result(len, -1);
stack<int> st;
st.push(0);
unordered_map<int, int> umap;
for(int i=0; i<len; i++){
nums.emplace_back(nums[i]);
umap[nums[i]] = i;
}
for(int i=1; i<2*len; i++){
while(!st.empty() && nums[i]>nums[st.top()]){
if(umap.count(nums[st.top()])>0 && result[st.top()%len]==-1){
result[st.top()%len] = nums[i];
}
st.pop();
}
st.push(i);
}
return result;
}
};
解法二(下标取余)
遍历范围扩大到2*nums.size(),在每次取值时对nums.size()取余。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
// c++
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int len = nums.size();
vector<int> result(len, -1);
stack<int> st;
st.push(0);
for(int i=1; i<2*len; i++){
while(!st.empty() && nums[i%len]>nums[st.top()%len]){
// 减少重复操作
if(result[st.top()%len]==-1){
result[st.top()%len] = nums[i%len];
}
st.pop();
}
st.push(i);
}
return result;
}
};