LeetCode 503 下一个更大元素II
题目链接:503. 下一个更大元素 II - 力扣(LeetCode)
【解题思路】
-
用一个单调栈记录遍历过元素的下标
-
当前元素下标的值比栈顶元素下标的值大
-
1.将栈顶元素弹出
-
2.将当前元素入栈
-
3.result数组记录当前元素的下标
-
-
当前元素下标的值等于栈顶元素下标的值
-
直接将当前元素加入单调栈
-
-
当前元素下标的值比栈顶元素下标的值小
-
直接将当前元素加入单调栈
-
-
思路1
-
先将数组扩充为二倍数组大小,计算出单调栈后再resize成原数组大小
-
扩充原数组的时间复杂度是O(n),较为耗时
-
-
-
思路2
-
可以用取模的方式来模拟成环遍历的过程
-
遍历时按二倍数组长度来遍历
-
取i时让i和nums.size()取模
-
-
【解题步骤】
-
1.定义一个栈st
-
2.定义一个result数组(结果集),大小为数组的大小,初始化为-1
-
4.循环遍历数组,遍历两倍的数组长度
-
让i和nums.xize()取模
-
当前遍历元素小于栈顶元素
-
直接将当前遍历元素下标加入栈里
-
-
当前遍历元素等于栈顶元素
-
直接将当前遍历元素下标加入栈里
-
-
当前遍历元素大于栈顶元素
-
一直将栈顶元素弹出,直到栈顶元素大于当前遍历元素
-
result[st.top()] = i-st.top()
-
-
-
-
5.return result
【代码部分】
class Solution {
public int[] nextGreaterElements(int[] nums) {
if(nums == null || nums.length <=1){
return new int[]{-1};
}
Stack<Integer> st = new Stack<>();
int[] result = new int[nums.length];
Arrays.fill(result,-1);
for (int i = 0; i < nums.length*2; i++) {
while(!st.isEmpty()&&nums[i%nums.length] > nums[st.peek()]){
result[st.peek()] = nums[i%nums.length];
st.pop();
}
st.push(i%nums.length);
}
return result;
}
}
LeetCode 42 接雨水
【解题思路】
-
求雨水面积,我们就需要知道当前容器的宽度
-
也就是当前柱子左边第一个比他高的元素,以及右边第一个比他高的元素
-
右边第一个比他大的元素怎么找
-
当前元素要是比栈顶元素大,那么当前元素就是栈顶元素右边第一个比他大的元素
-
-
左边第一个比他大的元素怎么找
-
因为是单调递增栈,所以栈内第二个元素其实就是左边第一个比栈顶元素大的元素
-
-
右边柱子下标减去左边柱子的下标就是宽度
-
-
找到容器的宽度之后,在左右两边的高度里求最小值
-
再用最小值减去中间柱子的高度
-
-
宽乘高=面积
-
当前元素下标的值比栈顶元素下标的值大
-
1.将栈顶元素弹出
-
2.将当前元素入栈
-
3.result数组记录当前元素的下标
-
-
当前元素下标的值等于栈顶元素下标的值
-
直接将当前元素加入单调栈
-
-
当前元素下标的值比栈顶元素下标的值小
-
直接将当前元素加入单调栈
-
【解题步骤】
-
1.定义一个栈st
-
2.将第一个元素入栈
-
4.循环遍历数组,i从1开始
-
当前遍历元素小于栈顶元素
-
直接将当前遍历元素下标加入栈里
-
-
当前遍历元素等于栈顶元素
-
直接将当前遍历元素下标加入栈里
-
-
当前遍历元素大于栈顶元素
-
一直将栈顶元素弹出,直到栈顶元素大于当前遍历元素
-
1.定义一个middle,将栈顶元素弹出并记录
-
2.如果当前栈不为空
-
1)将当前栈顶元素和当前元素取最小值,再用最小值减去中间柱子的高度
-
2)i-栈顶元素=宽
-
3)将计算的雨水面积做累加
-
-
-
最后将当前元素入栈
-
-
-
5.return result
【代码部分】
class Solution {
public int trap(int[] height) {
Stack<Integer> st = new Stack<>();
st.push(0);
int sum = 0;//存放结果
for (int i = 1; i < height.length; i++) {
if(height[i] < height[st.peek()]){
st.push(i);
}else if(height[i] == height[st.peek()]){
st.pop();
st.push(i);
}else {
while (!st.isEmpty()&&(height[i] > height[st.peek()])){
int mid = st.pop();
if(!st.isEmpty()){
int h = Math.min(height[st.peek()],height[i]) - height[mid];
int w = i - st.peek() - 1;
int hold = h*w;
if(hold > 0)sum +=hold;
}
}
st.push(i);
}
}
return sum;
}
}