classSolution{public:inttrap(vector<int>& height){int sum =0;for(int i =0; i < height.size(); i++){// 第一个柱子和最后一个柱子不接雨水if(i ==0|| i == height.size()-1)continue;int rHeight = height[i];// 记录右边柱子的最高高度int lHeight = height[i];// 记录左边柱子的最高高度for(int r = i +1; r < height.size(); r++){if(height[r]> rHeight) rHeight = height[r];}for(int l = i -1; l >=0; l--){if(height[l]> lHeight) lHeight = height[l];}int h =min(lHeight, rHeight)- height[i];if(h >0) sum += h;}return sum;}};
classSolution{public:inttrap(vector<int>& height){if(height.size()<=2)return0;
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;}};
单调栈:其实就是栈顶和栈顶的下一个元素以及要入栈的元素,三个元素来接水!
classSolution{public:inttrap(vector<int>& height){
stack<int> st;
st.push(0);int sum =0;for(int i =1; i < height.size(); i++){while(!st.empty()&& height[i]> height[st.top()]){int mid = st.top();
st.pop();if(!st.empty()){int h =min(height[st.top()], height[i])- height[mid];int w = i - st.top()-1;
sum += h * w;}}
st.push(i);}return sum;}};
classSolution{public:intlargestRectangleArea(vector<int>& heights){int sum =0;for(int i =0; i < heights.size(); i++){int left = i;int right = i;for(; left >=0; left--){if(heights[left]< heights[i])break;}for(; right < heights.size(); right++){if(heights[right]< heights[i])break;}int w = right - left -1;int h = heights[i];
sum =max(sum, w * h);}return sum;}};
双指针解法:
classSolution{public:intlargestRectangleArea(vector<int>& heights){
vector<int>minLeftIndex(heights.size());
vector<int>minRightIndex(heights.size());int size = heights.size();// 记录每个柱子 左边第一个小于该柱子的下标
minLeftIndex[0]=-1;// 注意这里初始化,防止下面while死循环for(int i =1; i < size; i++){int t = i -1;// 这里不是用if,而是不断向左寻找的过程while(t >=0&& heights[t]>= heights[i]) t = minLeftIndex[t];
minLeftIndex[i]= t;}// 记录每个柱子 右边第一个小于该柱子的下标
minRightIndex[size -1]= size;// 注意这里初始化,防止下面while死循环for(int i = size -2; i >=0; i--){int t = i +1;// 这里不是用if,而是不断向右寻找的过程while(t < size && heights[t]>= heights[i]) t = minRightIndex[t];
minRightIndex[i]= t;}// 求和int result =0;for(int i =0; i < size; i++){int sum = heights[i]*(minRightIndex[i]- minLeftIndex[i]-1);
result =max(sum, result);}return result;}};
单调栈解法:注意为什么要在数组头尾都加入元素0。
// 版本二classSolution{public:intlargestRectangleArea(vector<int>& heights){
stack<int> st;
heights.insert(heights.begin(),0);// 数组头部加入元素0
heights.push_back(0);// 数组尾部加入元素0
st.push(0);int result =0;for(int i =1; i < heights.size(); i++){while(heights[i]< heights[st.top()]){int mid = st.top();
st.pop();int w = i - st.top()-1;int h = heights[mid];
result =max(result, w * h);}
st.push(i);}return result;}};