單調棧題解
單調棧結構
方法:單調棧
算法
這裏維護一個單調遞增棧,可以找到比當前元素要小的元
約定:當前元素 cur,棧頂元素 top,出棧的棧頂元素 tempTop
- 遍歷數組
- 如果當前元素大於棧頂元素,則入棧(入棧元素索引,而不是值)
- 否則,將棧頂元素出棧,此時,離 tempTop 左邊最近且值比 tempTop 小的就是當前的棧頂元素 top,離 tempTop 右邊最近且值比 tempTop 小的就是當前元素 cur。 然後循環此過程,直到第二步條件滿足。
- 遍歷數組結束後,最後將棧內元素按上述規則輸出
private static void leftRightWay(int[] arr){
int len = arr.length;
int[] right = new int[len];
int[] left = new int[len];
Stack<Integer> stack = new Stack<>();
for(int i = 0; i < len; i++) {
while(!stack.empty() && arr[i] < arr[stack.peek()]) {
int tempTop = stack.pop();
left[tempTop] = stack.empty() ? -1 : stack.peek();
right[tempTop] = i;
}
stack.push(i);
}
while(!stack.empty()) {
int tempTop = stack.pop();
left[tempTop] = stack.empty() ? -1 : stack.peek();
right[tempTop] = -1;
}
for(int i = 0; i < len; i++) {
System.out.println(left[i] + " " + right[i]);
}
}
複雜度
- 時間複雜度:O(N),每個元素被處理兩次,其索引入棧和出棧。
739. 每日溫度
方法一:動態規劃,詳解可去鏈接裏查看
public int[] dailyTemperatures(int[] T) {
int len = T.length;
int[] result = new int[len];
result[len - 1] = 0;
for(int i = len - 2; i >= 0; i--) {
for(int j = i + 1; j < len; j += result[j]) {
// 重點在 j += result[j] 上
// 當天溫度小於後一天溫度,那麼直接得出結果 1
// 當天溫度大於後一天溫度,那麼就得比較 [比後一天溫度還要高的那一天],循環這個過程。
// 如果後一天溫度的後面沒有比它大的了,那自然也不可能比當天溫度大了
if (T[i] < T[j]) {
result[i] = j - i;
break;
} else if (result[j] == 0) {
result[i] = 0;
break;
}
}
}
return result;
}
方法二:單調棧
算法
維護一個單調遞減的棧即可,棧內存放的是元素索引
- 遍歷數組
- 如果當前元素小於棧頂元素,則入棧
- 否則,將棧頂元素出棧,
當前元素索引 - 棧頂元素
就是對應位置的結果
public int[] dailyTemperatures(int[] T) {
int len = T.length;
int[] result = new int[len];
Stack<Integer> stack = new Stack();
for(int i = 0; i < len; i++) {
while(!stack.empty() && T[i] > T[stack.peek()]) {
int tempTop = stack.pop();
result[tempTop] = i - tempTop;
}
stack.push(i);
}
while(!stack.empty()) {
result[stack.pop()] = 0;
}
return result;
}