前言
- 26回了老家参加二姨的婚礼,还逛了几圈亲戚,回来就接家教的活,想到还要刷题开组会,回家注定是没法怎么休息啦,可恶
42. 接雨水 - 力扣(LeetCode)
-
暴力解法(双指针优化)
- 寻找每一处两侧最高的列,按列计算雨水高度并相加,每次都向两边遍历有太多重复计算,优化方法是直接用数组存好左最高和右最高列的值
-
class Solution { public:int trap(vector<int>& height) {if (height.size() <= 2) return 0;vector<int> maxLeft(height.size(), 0);vector<int> maxRight(height.size(), 0);int size = maxRight.size();// 记录每个柱子左边柱子最大高度maxLeft[0] = height[0];for (int i = 1; i < size; i++) {maxLeft[i] = max(height[i], maxLeft[i - 1]);}// 记录每个柱子右边柱子最大高度maxRight[size - 1] = height[size - 1];for (int i = size - 2; i >= 0; i--) {maxRight[i] = max(height[i], maxRight[i + 1]);}// 求和int sum = 0;for (int i = 0; i < size; i++) {int count = min(maxLeft[i], maxRight[i]) - height[i];if (count > 0) sum += count;}return sum;} };
-
单调栈
- 依然是单调递增栈,当大于栈顶的时候,当前高度是右边第一个高,栈顶是mid,第二栈顶正好是左边第一高,根据h*w就可以算出总雨水高度(按行计算),需要注意的是,相同的元素也压入栈对于雨水计算无影响
-
class Solution { public:int trap(vector<int>& height) {stack<int> st;st.push(0);int sum = 0;for(int i = 1; i < height.size(); i++){if(height[i] <= height[st.top()]){st.push(i);}else{while(!st.empty() && height[i] > height[st.top()]){int mid = st.top(); // 记录当前元素st.pop(); // 弹出方便取第二if(!st.empty()){ // 只要取top就要判空int h = min(height[i], height[st.top()]) - height[mid];int w = i - st.top() - 1;sum += h * w;}}st.push(i);}}return sum;} };
84. 柱状图中最大的矩形 - 力扣(LeetCode)
- 整体思路和接雨水类似,区别:前后补0、单调递减栈、 计算矩形面积方式
-
class Solution { public:int largestRectangleArea(vector<int>& heights) {int sum = 0;heights.insert(heights.begin(), 0); // 前加0heights.push_back(0); // 后加0stack<int> st; // 递减栈st.push(0);for(int i = 1; i < heights.size(); i++){if(heights[i] >= heights[st.top()]){st.push(i);}else{while(!st.empty() && heights[i] < heights[st.top()]){int mid = st.top();int right = i;st.pop();if(!st.empty()){int left = st.top();int w = right - left - 1;int h = heights[mid];sum = max(sum, w * h);}}st.push(i);}}return sum;} };
后言
- 本来想着回家可能刷题能更投入点,但是还是低估了回来各种杂事的程度,唉...以撒启动!