网站分站如何做,上海建筑设计院官网,wordpress会员支付系统,郑州企业网站排名739. 每日温度
单调栈应该从栈底到栈顶 是递减的。
找下一个更大的 #xff0c;用递减单调栈#xff0c;就可以确定在栈里面的每个比当前元素i小的元素#xff0c;下一个更大的就是这个i#xff0c;然后弹出并记录#xff1b;然后当前元素i入栈#xff0c;仍然满足递减…739. 每日温度
单调栈应该从栈底到栈顶 是递减的。
找下一个更大的 用递减单调栈就可以确定在栈里面的每个比当前元素i小的元素下一个更大的就是这个i然后弹出并记录然后当前元素i入栈仍然满足递减要求。最后留在栈里面的是没有下一个更大的值的符合要求。
找下一个更小的用递增单调栈同理。
result[被弹出下标]使他弹出下标-被弹出下标。
复习一下Java集合知识来自Java集合详解-CSDN博客 LinkedList 可以使用多种接口进行声明包括但不限于
Deque 接口DequeInteger deque new LinkedList();: 双端队列的操作包括栈和队列的功能。Queue 接口QueueInteger queue new LinkedList();: 适合实现队列的操作包括 offer、poll、peek 等方法。List 接口ListInteger list new LinkedList();: 通用的集合操作如添加、删除、获取元素等。Collection 接口CollectionInteger collection new LinkedList();: 这种声明方式表示通用的集合操作适合需要简单地操作元素集合的场景。
class Solution {public int[] dailyTemperatures(int[] temperatures) {int ntemperatures.length;DequeInteger stacknew LinkedList();//放下标int [] result new int[n];for(int i0;in;i){int temptemperatures[i];while(!stack.isEmpty() temperatures[stack.peek()]temp){int astack.pop();//小被弹出result[a]i-a;}//找到位置stack.push(i);}return result;}
}
时间、空间O(n)
496. 下一个更大元素 I
跟上一题区别是先用单调栈把nums2处理较小的元素弹出来的时候要找到当前元素i在nums1的位置然后给到result。
这里不算下标而且数组里面没有重复元素所以单调栈里面可以放元素值。
另外result一开始都赋值-1。最后可能nums1里有几个是没有下一个更大值的。
class Solution {public int[] nextGreaterElement(int[] nums1, int[] nums2) {int mnums1.length ,nnums2.length ;DequeInteger stacknew LinkedListInteger();int[] resultnew int[m];HashMapInteger,Integer hashnew HashMap();// 放元素for(int i0;im;i){hash.put(nums1[i],i);}for(int i0;im ;i){result[i]-1;}for(int i0;in;i){int tmpnums2[i];while(!stack.isEmpty() stack.peek()tmp){int astack.pop();//被弹出的元素aint poshash.getOrDefault(a,-1);if(pos!-1)result[pos]tmp;}stack.push(tmp);}return result;}
}
时间是O(mn)。初始化result和hash的是O(m)单调栈循环是O(n)因为用的HashMap查找O(1)。
503. 下一个更大元素 II
要求循环地搜索元素的下一个更大的数其实就是单调栈要走两次nums数组。
class Solution {public int[] nextGreaterElements(int[] nums) {int nnums.length;int[] resultnew int[n];DequeInteger stacknew LinkedList();Arrays.fill(result,-1);for(int j0;j2*n;j){int ij%n;int numnums[i];while(!stack.isEmpty() nums[stack.peek()]num){int astack.pop();result[a]nums[i];}stack.push(i);}return result;}
}
42. 接雨水
1、以列为单位每列都找自己左边包含自己的最高柱子 l 和自己右边包含自己的最高柱子 r就形成一个凹槽。然后每一列应该装下的雨水数就应该是min(l , r) - 自己柱子高*宽。所以主要关注l 和 r 怎么计算。
1.1、DP
维护一个lefts和rights数组lefts[i]是lrights[i]就是r。
那么递推公式就是min(lefts[i] , rights[i]) - 自己柱子高*宽
关键得到这两个数组还是很直观的lefts涉及到的是i及左边的所以从左往右递推rights从右往左。
class Solution {public int trap(int[] height) {int nheight.length;int count0;int[] leftsnew int[n];int[] rightsnew int[n];lefts[0]height[0];for(int i1;in;i){lefts[i]Math.max(lefts[i-1],height[i]);}rights[n-1]height[n-1];for(int in-2;i0;--i){rights[i]Math.max(rights[i1],height[i]);}for(int i0;in;i){count(Math.min(lefts[i],rights[i])-height[i]);}return count;}
}
时间空间On 1.2、双指针
用两个指针left、right从两端逐渐逼近逼近的判断条件是left指向的和right指向的对比哪一方小就走一步。 ①这里对于红框的判断不能理解为什么当前的哪一方小就能确定这一方的最大值更小呢
下面这个说法很形象。其实就是A队B队比赛遍历过了的都是输了的或者平局的假如B队的curB赢了A队的curA所以目前MAX_B其实就是curB是目前两队最强。即A队最强的其实是输给B队过的了所以A队最强不如B队最强。可以确定MAX_BcurBMAX_A。A赢B就同理。
②又想假如B队赢了A队可以确定出现了一个凹槽A队最高、curA、B队最高。这个凹槽的两端一定是我们要求的吗
A队最高肯定是所要求的左边最高柱子l B队最高不一定是右边最高柱子 r。假如curA和curB之间还有比MAX_A更矮的柱子压根不考虑因为我们是先找两端最高的再在两个最高的里找最小的假如有比MAX_B更高的柱子那取Min值仍然还是MAX_A。A赢B就同理。
总的来说哪一方输了哪一方的输家就可以确定他的雨水了。决定这个雨水高度的就是他这一方的最强者但是比另一方的最强者弱。 可以用MAX_BMAX_A用height[a]height[b]感觉更能体现这个“比赛”的过程吧当前选手的大小。
class Solution {public int trap(int[] height) {int nheight.length;int a0,bn-1;//对手int MAX_A0,MAX_B0;//一个队里面已比对手的最强者int count0;while(ab){//更新最强者要包括当前选手MAX_AMath.max(MAX_A,height[a]);MAX_BMath.max(MAX_B,height[b]);int yushui0;//输的一方收集雨水if(height[a]height[b])//b整体赢了{yushuiMAX_A-height[a];//注意凹槽两端a;//输的下场派下一个}else if(height[a]height[b]){yushuiMAX_B-height[b];b--; }countyushui;}return count;}
}
时间O(n)空间O(1)
2、以行为单位
2.1 单调栈
以列为单位求每个柱子的雨水是一次性求好需要提前知道左边最高柱子和右边最高柱子这形成凹槽1
以行为单位求是求以每个柱子为底的这一行能接的雨水这一行雨水可以到的高度应该是最接近自己的柱子的最小高度。即Min上一个更大下一个更大。这是凹槽2。
这是按行求 和 按列求 的主要区别。
这一行宽是 下一个更大和上一个更大的 下标间隔。高是Min值和中间 a 的差。
class Solution {public int trap(int[] height) {int nheight.length;int count0;DequeInteger stacknew LinkedListInteger ();for(int i0;in;i){int tmpheight[i];while(!stack.isEmpty() height[stack.peek()]tmp)//凹槽{int astack.pop();//l栈底arheight[i]if(!stack.isEmpty()){int lstack.peek();int ri;int kuanr-l-1;int gaoMath.min(height[l],height[r])-height[a];countkuan*gao;}}stack.push(i);}return count;}
}
84. 柱状图中最大的矩形