classSolution{publicint[]dailyTemperatures(int[] temperatures){//定义单调栈存储下标,栈头到栈底递增Deque<Integer> stack =newLinkedList<>();//定义结果数组并初始化为全0int[] result =newint[temperatures.length];//遍历温度数组for(int i =0; i < temperatures.length; i++){//如果当前元素大于栈顶元素,则取出栈顶元素,并赋值(当前下标减去栈顶元素)给结果数组对应下标while(stack.peek()!=null){if(temperatures[i]> temperatures[stack.peek()]){int top = stack.pop();
result[top]= i - top;}else{//直到栈顶元素小于当前元素,当前元素入栈
stack.push(i);break;}}//栈空,当前元素入栈if(stack.peek()==null){
stack.push(i);}}//返回结果return result;}}
classSolution{publicinttrap(int[] height){//双指针//按列计算,当前列的雨水量为左侧最高和右侧最高中的较小值减去当前列高度//第一列和最后一列不能接雨水int sum =0;for(int i =1; i < height.length -1; i++){//定义当前列左右侧最高int left =0;int right =0;//分别查找左右最高for(int j = i -1; j >=0; j--){
left =Math.max(height[j], left);}for(int k = i +1; k < height.length; k++){
right =Math.max(height[k], right);}//求和int rain =Math.min(left, right)- height[i];if(rain >0) sum += rain;}//返回结果return sum;}}
DP:
classSolution{publicinttrap(int[] height){//DPint[] dpLeft =newint[height.length];int[] dpRight =newint[height.length];//遍历一遍保存到两个一维数组中(分别存当前列的左右侧最高)//遍历一遍进行初始化for(int i =1; i < height.length -1; i++){int left =0;int right =0;for(int j = i -1; j >=0; j--){
left =Math.max(left, height[j]);}for(int k = i +1; k < height.length; k++){
right =Math.max(right, height[k]);}
dpLeft[i]= left;
dpRight[i]= right;}//递推遍历int sum =0;for(int j =1; j < height.length -1; j++){int rain =Math.min(dpLeft[j], dpRight[j])- height[j];if(rain >0) sum += rain;}//返回结果return sum;}}
单调栈:
classSolution{publicinttrap(int[] height){//单调栈//定义单调(递增)栈存储柱子对应下标Deque<Integer> stack =newLinkedList<>();//初始化
stack.push(0);int sum =0;//遍历for(int i =1; i < height.length; i++){int top = stack.peek();if(height[i]< height[top]){//小于栈顶元素直接入栈
stack.push(i);}elseif(height[i]== height[top]){//等于栈顶元素则替换栈顶元素
stack.pop();
stack.push(i);}else{//大于栈头元素高度,则栈头位置可以接雨水//每弹出一个元素就计算雨水量while(!stack.isEmpty()&& height[stack.peek()]< height[i]){int mid = stack.pop();if(!stack.isEmpty()){//雨水量为宽乘高int h =Math.min(height[stack.peek()], height[i])- height[mid];int w = i - stack.peek()-1;int rain = h * w;if(rain >0) sum += rain;}}//计算结束后弹出栈头元素直到当前元素(高度递增)入栈
stack.push(i);}}//返回结果return sum;}}
classSolution{publicintlargestRectangleArea(int[] heights){//DPint[] dpLeft =newint[heights.length];int[] dpRight =newint[heights.length];//初始化
dpLeft[0]=-1;
dpRight[heights.length -1]= heights.length;//分别遍历保存到两个一维数组中(分别存当前列的左右侧第一个小于)for(int i =1; i < heights.length; i++){int m = i -1;while(m >=0&& heights[i]<= heights[m]) m = dpLeft[m];
dpLeft[i]= m;}for(int j = heights.length -2; j >=0; j--){int m = j +1;while(m < heights.length && heights[j]<= heights[m]) m = dpRight[m];
dpRight[j]= m;}//递推遍历求和int sum =0;for(int i =0; i < heights.length; i++){int h = heights[i];int w = dpRight[i]- dpLeft[i]-1;
sum =Math.max(sum, h * w);}//返回结果return sum;}}
单调栈:
classSolution{publicintlargestRectangleArea(int[] heights){//单调栈//定义单调(递减)栈存储柱子对应下标Deque<Integer> stack =newLinkedList<>();//初始化//这里将数组扩容,两头加0,两边最小能到首尾int[] heights2 =newint[heights.length +2];
heights2[0]=0;for(int i =0; i < heights.length; i++){
heights2[i +1]= heights[i];}
heights2[heights2.length -1]=0;
stack.push(0);int sum =0;//遍历for(int i =1; i < heights2.length; i++){int top = stack.peek();if(heights2[i]> heights2[top]){//大于栈顶元素直接入栈
stack.push(i);}elseif(heights2[i]== heights2[top]){//等于栈顶元素则替换栈顶元素
stack.pop();
stack.push(i);}else{//小于栈头元素高度,则计算面积//每弹出一个元素就计算雨水量while(!stack.isEmpty()&& heights2[i]< heights2[stack.peek()]){int mid = stack.pop();if(!stack.isEmpty()){//面积为宽乘高int h = heights2[mid];int w = i - stack.peek()-1;
sum =Math.max(sum, h * w);}}//计算结束后弹出栈头元素直到当前元素(高度递增)入栈
stack.push(i);}}//返回结果return sum;}}