题目:503.下一个更大元素II
文章链接:代码随想录
题目链接:力扣题目链接
图释:
// 将循环数组拼接成一个长数组
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
// 复制定义
vector<int> nums1(nums.begin(), nums.end());
// 插入
nums.insert(nums.end(), nums1.begin(), nums1.end());
// 按新的nums定义结果数组
vector<int>result(nums.size(), -1);
if(nums.size()==0)return result;
// 开始单调栈
stack<int>st;
st.push(0); //放入的是下标
for(int i=1; i<nums.size(); i++){
// 情况1、2
if(nums[i]<=nums[st.top()]) st.push(i);
//情况3
else{
while(!st.empty() && nums[i]>nums[st.top()]){
result[st.top()]=nums[i]; // 找的是下一个更大的元素
st.pop(); // 弹出
}
st.push(i);
}
}
// 最后输出结果为一半
result.resize(nums.size()/2);
return result;
}
};
// 模拟遍历两边nums,用i%nums.size()进行操作,相除取余
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
// 初始化结果数组
vector<int>result(nums.size(), -1);
if(nums.size()==0)return result;
// 开始单调栈
stack<int>st;
st.push(0); //放入的是下标
for(int i=1; i<nums.size()*2; i++){
// 情况1、2 模拟遍历两边nums,用i%nums.size()进行操作,相除取余
if(nums[i%nums.size()]<=nums[st.top()]) st.push(i%nums.size());
//情况3
else{
while(!st.empty() && nums[i%nums.size()]>nums[st.top()]){
result[st.top()]=nums[i%nums.size()]; // 找的是下一个更大的元素
st.pop(); // 弹出
}
st.push(i%nums.size());
}
}
return result;
}
};
// 对三种情况进行一个合并
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
// 初始化结果数组
vector<int>result(nums.size(), -1);
if(nums.size()==0)return result;
// 开始单调栈
stack<int>st;
for(int i=0; i<nums.size()*2; i++){
// 三种情况进行合并
while(!st.empty() && nums[i%nums.size()]>nums[st.top()]){
result[st.top()]=nums[i%nums.size()]; // 找的是下一个更大的元素
st.pop(); // 弹出
}
st.push(i%nums.size());
}
return result;
}
};
题目:42. 接雨水
文章链接:代码随想录
视频链接:LeetCode:42.接雨水
题目链接:力扣题目链接
图释:
// 用双指针的方式,动态规划左右两遍的高度
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;
}
};
class Solution {
public:
int trap(vector<int>& height) {
if(height.size() <=2) return 0; // 不足以构成水槽
stack<int> st; //存放下标, 计算时还是用下标去找柱子高度
st.push(0);
int sum= 0; //结果输出
for(int i=1; i<height.size(); i++){
if(height[i] < height[st.top()]){ // 情况1
st.push(i);
}else if(height[i] == height[st.top()]){ //情况2:当两个柱子相同时,需要先把第一个柱子拿出来,放入新的柱子
st.pop();
st.push(i);
}else{ //情况3
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;
}
};