算法刷题记录 Day51
Date: 2024.04.19
lc 42. 接雨水
// 单调栈
class Solution {
public:int trap(vector<int>& height) {// 思路2:单调栈。当有个元素要入栈时。若该元素小于等于栈顶,则直接入栈;// 若该元素大于栈顶,则出栈。出栈后的新的栈顶,就是该出栈元素的左侧最大值。// (当前索引-新栈顶索引-1) * (min(左,右)-当前), 即为累计的雨水;// 若出栈后无元素,则该元素自身为最大值,不统计该出栈值接了多少雨水。int n = height.size();int cur_idx = 0;stack<int> st; // 存放单调栈的索引;int sum = 0;while(cur_idx < n){while(!st.empty() && height[cur_idx] >= height[st.top()]){int cur_pop_idx = st.top();st.pop();if(st.empty()){ //若出栈一个值后栈空,则该值自身为最大值,不累加雨水}else{// cout<<(min(height[cur_idx], height[st.top()]) - height[cur_pop_idx]) * (cur_idx-st.top()-1))<<endl;// cout<<"当前索引:"<<cur_pop_idx<<endl;// cout<<"前一索引:"<<st.top()<<endl;// cout<<"后一索引:"<<st.top()<<endl;// cout<<"当前累加值:("<<min(height[cur_idx], height[st.top()])<<" - "<<height[cur_pop_idx]<< ") * "<<(cur_idx-st.top()-1)<<endl;sum += (min(height[cur_idx], height[st.top()]) - height[cur_pop_idx]) * (cur_idx-st.top()-1);}}st.push(cur_idx);cur_idx++;}return sum;}
};// 双指针
class Solution {
public:int trap(vector<int>& height) {// 对于每个柱子(除头尾),能够接水的量是其左侧和右侧最大值中的较小值。// 因此,使用双指针,遍历两次数组,获取每个位置的左侧最大值和右侧最大值。// 再遍历一次数组,计算每个位置能接的雨水量并累计。int n = height.size();vector<int> leftHeight(n, 0);vector<int> rightHeight(n, 0);int left_max = height[0];for(int i=1; i<n; i++){leftHeight[i] = left_max;left_max = max(left_max, height[i]);}int right_max = height[n-1];for(int i=n-2; i>=0; i--){rightHeight[i] = right_max;right_max = max(right_max, height[i]);}int sum = 0;for(int i=1; i<n-1; i++){sum += max(min(leftHeight[i], rightHeight[i]) - height[i], 0);}return sum;}
};
lc 503. 下一个更大元素II
class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {// 相当于把两个数组相连后进行处理。vector<int> next(nums.size(), -1);int cur_idx = 0;stack<int> st;while(cur_idx < 2*nums.size()){int tmp_idx = cur_idx % nums.size();while(!st.empty() && nums[tmp_idx] > nums[st.top()]){if(next[st.top()] == -1){next[st.top()] = nums[tmp_idx];}st.pop();}st.push(tmp_idx);cur_idx++;}return next;}
};