LeetCode 739. 每日温度
题目链接:739. 每日温度 - 力扣(LeetCode)
单调栈开始,为什么要用栈,因为栈是先入后出,当我们遍历从前往后的时候,每次遍历的元素都是添加至栈尾,方便我们进行比较,满足条件计算下标差值(因为是求几天后比今天热),不满足就继续走。
代码:
#python //数组中每一位表示之后比今天温度高的天数距离
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
res = [0 for _ in range(len(temperatures))] //每个的长度
stack = [] //初始化一个空栈
for i in range(len(temperatures)):
while len(stack) > 0 and temperatures[i] > temperatures[stack[-1]]: #如果大,就继续,如果小,啥都不操作,继续stack.append
res[stack[-1]] = i - stack[-1] #stack[-1]是满足条件的下标,i - stack[-1]是距离
stack.pop() #用完了丢掉
stack.append(i) #第一步,要把当前的下标放入栈中
return res
/Java 超时了
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
if(temperatures.length == 1){
return new int[0];
}
int[] dp = new int[temperatures.length];
// Arrays.fill(dp, Integer.MAX_VALUE);
dp[dp.length - 1] = 0;
for(int i = 0; i < temperatures.length - 1; i++){
for(int j = i + 1; j < temperatures.length; j++){
if(temperatures[j] > temperatures[i]){
// dp[i] = Math.min(dp[i], j - i);
dp[i] = j - i;
break;
}
}
}
return dp;
}
}
/Java
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] result = new int[n]; // 结果数组,初始化所有元素为0,表示还未找到下一个更高温度
Deque<Integer> stack = new ArrayDeque<>(); // 单调递减栈,保存数组下标
for (int i = 0; i < n; i++) {
// 当栈非空且当前温度高于栈顶索引对应的温度时,持续出栈,并更新result
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
int prevIndex = stack.pop();
result[prevIndex] = i - prevIndex; // 计算天数差
}
// 当前温度入栈
stack.push(i);
}
return result;
}
}
LeetCode 496.下一个更大元素 I
题目链接:496. 下一个更大元素 I - 力扣(LeetCode)
先看是示例,题目意思是nums1中每个元素存在与nums2,对nums1中每个元素在nums2中对应位置之后进行判别,找到更大的元素,同样和上一题一样涉及到了位置距离的判别,因此同样使用单调栈。
代码:
#python
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
stack = []
nums2_next_greater = {} # 用于存储nums2中每个元素的下一个更大的元素
# 首先,找出nums2中每个元素的下一个更大的元素
for num in nums2:
while stack and num > stack[-1]:
nums2_next_greater[stack.pop()] = num
stack.append(num)
# 处理栈中剩余的元素,它们没有下一个更大的元素
while stack:
nums2_next_greater[stack.pop()] = -1
# 对于nums1中的每个元素,查找其在nums2中的下一个更大的元素
res = [nums2_next_greater.get(num, -1) for num in nums1]
return res
/Java
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int[] dp = new int[nums1.length];
for(int i = 0; i < nums1.length; i++){
for(int j = 0; j < nums2.length; j++){
if(nums1[i] == nums2[j] && j < nums2.length - 1){
for(int k = j + 1; k < nums2.length; k++){
if(nums2[k] > nums1[i]){
dp[i] = nums2[k];
break;
}
}
}
}
dp[i] = dp[i] != 0 ? dp[i] : - 1;
}
return dp;
}
}
/Java
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int[] dp = new int[nums1.length];
Arrays.fill(dp, -1); // 初始化dp数组为-1,表示初始时还没有找到更大的元素
// 创建一个HashMap来存储nums2中每个元素及其对应的下一个更大元素
Map<Integer, Integer> nextGreater = new HashMap<>();
Stack<Integer> stack = new Stack<>();
// 找到nums2中每个元素的下一个更大元素
for (int num : nums2) {
while (!stack.isEmpty() && num > stack.peek()) {
nextGreater.put(stack.pop(), num);
}
stack.push(num);
}
// 在nums1中查找每个元素对应的下一个更大元素
for (int i = 0; i < nums1.length; i++) {
dp[i] = nextGreater.getOrDefault(nums1[i], -1);
}
return dp;
}
}