代码随想录算法训练营第四十五天| 503.下一个更大元素II 42. 接雨水

503.下一个更大元素II 

要求:

数组是环,需要找到下一个最大的元素

思路1:

先作为直线遍历,然后没有的节点,放到首部,再找比他大的节点

注意:头节点

代码:

 1 // 要求:返回循环数组中下一个更大的数字步数
 2 // 思路:先不循环遍历,
 3 // 然后对每个-1节点,以他为起始,放到数组的开头,计算有几个,仅计算一遍
 4 //
 5 vector<int> nextGreaterElements_complicate(vector<int>& nums) {
 6     vector<int> result(nums.size(), INT_MIN);
 7     stack<int> st;
 8 
 9     st.push(0);
10     for (int i = 1; i < nums.size(); i++)
11     {
12         if (nums[i] <= nums[st.top()])
13         {
14             st.push(i);
15         }
16         else
17         {
18             while (!st.empty() && nums[i] > nums[st.top()])
19             {
20                 result[st.top()] = nums[i];
21                 st.pop();
22             }
23             st.push(i);
24         }
25     }
26 
27     for (int i = 1; i < nums.size(); i++)
28     {
29         if (result[i] == INT_MIN)
30         {
31             cout << result[i] << endl;
32             for (int j = 0; j < i; j++)
33             {
34                 if (nums[i] < nums[j])
35                 {
36                     result[i] = nums[j];
37                     break;
38                 }
39             }
40         }
41         if (result[i] == INT_MIN)
42         {
43             result[i] = -1;
44         }
45     }
46 
47     if(result[0]== INT_MIN)result[0] = -1;
48 
49     return result;
50 }

 

思路2:

模拟遍历两次,也就是重复的把前面的节点,放到后面节点的后面

代码:

 1 // 新思路:模拟走两边,这样就可以把前面的节点放到后面的节点的后边
 2 //
 3 vector<int> nextGreaterElements(vector<int>& nums) {
 4     vector<int> result(nums.size(),-1);
 5     stack<int>st;
 6 
 7     st.push(0);
 8     for (int i = 1; i < nums.size() * 2; i++)
 9     {
10         if (nums[i % nums.size()] <= nums[st.top()])
11         {
12             st.push(i % nums.size());
13         }
14         else
15         {
16             while (!st.empty() && nums[i % nums.size()] > nums[st.top()])
17             {
18                 result[st.top()] = nums[i % nums.size()];
19                 st.pop();
20             }
21 
22             st.push(i % nums.size());
23         }
24     }
25 
26     return result;
27 }

 42. 接雨水  

要求:

给一组数组,然后把雨水放到里面的凹槽中

思路1:

找出左边和右边最低的高度,然后 和 自己的高度相减,就是目前的雨水

注意 :首尾不算

思路2:

找到右边最高的高度

左右中最低的高度-本身,就是水的高度,然后再*长度,就是体积

代码:

 1 // 要求:当前节点找到最近比他大或等于的节点,以当前节点填充当前节点和最大节点之间的数值
 2 // 公式:min(左侧最高,右侧最奥)-height 
 3 // 注意首尾不接水
 4 // 
 5 // 思路1:
 6 // 当前仅算右侧最高,并没有算左侧最高
 7 // 思路2:
 8 // 横向:
 9 //    小于,放进去,等于,踢出来
10 //    大于,当前节点就是底部,左边和右边最小值-底部,就是雨水的高度,然后左-右-1,就是长度
11 //
12 int trap(vector<int>& height) {
13     // 存放当前节点 <= 节点的下标
14     int result = 0;
15     stack<int> st;
16 
17     st.push(0);
18     for (int i = 1; i < height.size(); i++)
19     {
20         if (height[i] < height[st.top()])
21         {
22             st.push(i);
23         }
24         else if (height[i] == height[st.top()]) {
25             st.pop();
26             st.push(i);
27         }
28         else
29         {
30             while (!st.empty() && height[i] > height[st.top()])
31             {
32                 int mid = st.top(); st.pop();
33 
34                 if (!st.empty())
35                 {
36                     int left = st.top();
37                     int right = i;
38 
39                     int height_ = min(height[right], height[left]) - height[mid];
40 
41                     int width = right - left - 1;
42 
43                     result += height_ * width;
44                 }
45             }
46 
47             st.push(i);
48         }
49 
50     }
51 
52 
53     return result;
54 }

 

posted @ 2023-08-04 10:06  博二爷  阅读(12)  评论(0编辑  收藏  举报