739. 每日温度
思路
暴力1
- 两层for循环,外层遍历数组,内层遍历寻找比当前温度更高的一天
暴力2
-
设置next数组记录每个温度第一次出现的下标,next的下标为对应温度,next初始化为无穷大
-
外层反向遍历温度数组,内层从下标为temperatures[i]+1到100遍历next数组
-
- 寻找next数组中比当前温度高的最小下标,记为warmerIndex
- 如果warmerIndex不为无穷大,说明有比当前温度更高的温度,记录结果
单调栈
-
维护一个存储下标的单调栈,从栈底到栈顶保持单调递减
-
如果一个下标在单调栈里,则表示尚未找到下一次温度更高的下标
-
- 当前遍历元素大于栈顶元素,则栈中元素出栈记录等待天数,直至栈顶元素大于遍历元素或栈空
- 当前遍历元素小于等于栈顶元素,当前遍历元素入栈
-
单调栈主要就是维护需要值的单调性, 通常是前面的值需要后面的值来进行判断,因此需要保存前面的这些值的位置,以便在后序出现更大元素时得到结果
代码
暴力1
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int> res;
int j;
for(int i=0;i<temperatures.size();i++){
for(j=i+1;j<temperatures.size();j++){
if(temperatures[j]>temperatures[i]){
res.push_back(j-i);
break;
}
}
if(j==temperatures.size()) res.push_back(0);
}
return res;
}
};
- 时间复杂度
O(n^2)
(超时) - 空间复杂度
O(1)
暴力2
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int> next(101,INT_MAX);
vector<int> ans(temperatures.size());
for(int i=temperatures.size()-1;i>=0;i--){
int warmerIndex=INT_MAX;
for(int j=temperatures[i]+1;j<=100;j++){
warmerIndex=min(warmerIndex,next[j]);
}
if(warmerIndex!=INT_MAX){
ans[i]=warmerIndex-i;
}
next[temperatures[i]]=i;
}
return ans;
}
};
- 时间复杂度
O(nm)
- 空间复杂度
O(m)
单调栈
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> st;
vector<int> res(temperatures.size(),0);
for(int i=0;i<temperatures.size();i++){
while(!st.empty()&&temperatures[i]>temperatures[st.top()]){
res[st.top()]=i-st.top();
st.pop();
}
st.push(i);
}
return res;
}
};
- 时间复杂度
O(n)
- 空间复杂度
O(n)
496.下一个更大元素 I
思路
暴力解
- 在nums2找到nums1[i]的位置,然后搜索比nums1[i]第一个更大的元素
单调栈
方法一:
- nums1做哈希映射,key=nums1[i],value=i,在遍历nums2时可以快速查询元素是否在nums1中出现过,仅将出现过的元素作判断
- 遍历nums2数组,只将map中存在的nums2[i]对应的nums1的下标入单调栈
- 当遇到nums2[i]大于栈顶元素时,保存结果,出栈
方法二:
- 计算得到nums2数组每个元素的下一个更大元素,并将结果存储为哈希映射,即key=当前元素值,value=当前元素的下一个更大元素值
- 遍历nums1数组,在map中查询,存入结果
代码
暴力解
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
//暴力解
vector<int> res(nums1.size(),-1);
int j;
for(int i=0;i<nums1.size();i++){
for(j=0;j<nums2.size();j++){
if(nums1[i]==nums2[j]) break;
}
for(int k=j+1;k<nums2.size();k++){
if(nums2[k]>nums1[i]){
res[i]=nums2[k];
break;
}
}
}
return res;
}
};
- 时间复杂度
O(mn)
- 空间复杂度
O(1)
单调栈
方法一:
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int> map;
for(int i=0;i<nums1.size();i++)
map[nums1[i]]=i;
stack<int> st;
vector<int> res(nums1.size(),-1);
for(int i=0;i<nums2.size();i++){
while(!st.empty()&&nums2[i]>nums1[st.top()]){
res[st.top()]=nums2[i];
st.pop();
}
if(map.find(nums2[i])!=map.end()) st.push(map[nums2[i]]);
}
return res;
}
};
- 时间复杂度
O(m+n)
- 空间复杂度
O(m)
方法二:
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int> map;
stack<int> st;
// 计算得到nums2数组每个元素的下一个更大元素,并将结果存储为哈希映射
for(int i=0;i<nums2.size();i++){
while(!st.empty()&&nums2[i]>nums2[st.top()]){
map[nums2[st.top()]]=nums2[i]; // key=当前元素值,value=当前元素的下一个更大元素值
st.pop();
}
st.push(i);
}
//遍历nums1数组,在map中查询,存入结果
vector<int> res(nums1.size(),-1);
for(int i=0;i<nums1.size();i++)
if(map.find(nums1[i])!=map.end()) res[i]=map[nums1[i]];
return res;
}
};
- 时间复杂度
O(m+n)
- 空间复杂度
O(m)