题目链接:https://leetcode-cn.com/problems/daily-temperatures/
1.单调栈
思路如下:
单调栈常用于找出每个数左右两边离它最近的比它大/小的数。
C++代码如下:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> res(n);
stack<int> stk;
for (int i = 0; i < n; i++) {
while (!stk.empty() && temperatures[i] > temperatures[stk.top()]) {
res[stk.top()] = i - stk.top();
stk.pop();
}
stk.push(i);
}
return res;
}
};
2.倒推法(动态规划)
思路如下:
i
用来扫描所有的元素,从右往左扫描,一开始 i
指向倒数第 2 个元素。
对于每一个 i
,一开始令 j = i + 1
:
(1) 如果 temperatures[i] < temperatures[j]
,那么 res[i] = j - i
,然后 i--
(2) 如果 temperatures[i] == temperatures[j]
- 如果
res[j] == 0
,那么res[i] = 0
,然后i--
- 如果
res[j] != 0
,那么res[i] = res[j] + j - i
,然后i--
(3) 如果 temperatures[i] > temperatures[j]
- 如果
res[j] == 0
,那么res[i] = 0
,然后i--
- 如果
res[j] != 0
,那么j = j + res[j]
,重新进入 (1) 的判断
C++代码如下:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> res(n);
for (int i = n - 2; i >= 0; i--) {
int j = i + 1;
while (true) {
if (temperatures[i] < temperatures[j]) {
res[i] = j - i;
break;
} else if (res[j] == 0) {
res[i] = 0;
break;
} else if (temperatures[i] == temperatures[j]) {
res[i] = res[j] + j - i;
break;
} else {
j = j + res[j];
}
}
}
return res;
}
};
简化上面的代码:
i
用来扫描所有的元素,从右往左扫描,一开始 i
指向倒数第 2 个元素。
对于每一个 i
,一开始令 j = i + 1
:
(1) 如果 temperatures[i] < temperatures[j]
,那么 res[i] = j - i
,然后 i--
(2) 如果 res[j] == 0
,那么 res[i] = 0
,然后 i--
(3) 否则,设置 j = j + res[j]
,回到步骤 (1)
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> res(n);
for (int i = n - 2; ~i; i--) {
int j = i + 1;
while (true) {
if (temperatures[i] < temperatures[j]) {
res[i] = j - i;
break;
} else if (res[j] == 0) {
res[i] = 0;
break;
}
j = j + res[j];
}
}
return res;
}
};