“即使到不了远方,心中也要有远方的模样。”
1.leetcode 503. 下一个更大元素Ⅱ
1.1 详细思路及步骤
这题基本上和昨天总结的两个题思路是一模一样的,区别不同的就是,这是一个循环数组,那就直接将两个数组链接就好了。昨天的–>点这里
1.2 java版代码示例
class Solution {
public int[] nextGreaterElements(int[] nums) {
int len=nums.length;
int[] result=new int[len];
if(nums == null || nums.length<=1)return new int[]{-1};
Arrays.fill(result,-1);
Deque<Integer> stack = new LinkedList<Integer>();//用Deque也能做单调栈
// Stack<Integer> stack= new Stack<>();
// stack.push(0);
for(int i=0;i<len*2-1;i++){
while(!stack.isEmpty()&&(nums[i%len]>nums[stack.peek()])){
result[stack.pop()]=nums[i%len];
}
stack.push(i%len);
}
return result;
}
}
2.leetcode 42.接雨水
2.1 详细思路及步骤
这题首先拿着可能不好分析,那么就先光看局部,从局部分析,判断i位置能接的雨水就找到i位置右边和左边的最大值,然后比较这俩最大值的最小值,也就是i位置能装的水就是Math.min(left_max,right_max)-height[i]
然后先看暴力解法
class Solution {
public int trap(int[] height) {
int len=height.length;
int res=0;
for(int i=0;i<len;i++){
int l_max=0,r_max=0;
//求i右边的最大值
for(int j=i;j<len;j++){
l_max=Math.max(l_max,height[j]);
}
//求i左边的最大值
for(int j=i;j>=0;j--){
r_max=Math.max(r_max,height[j]);
}
res+=Math.min(l_max,r_max)-height[i];
}
return res;
}
}
根据暴力解法继续优化,上面的每次遍历i都会将i左边和右边的最大值遍历出来,其实也可以先将这俩遍历存储到数组中,然后直接用。
优化过程
class Solution {
public int trap(int[] height) {
if (height.length == 0) {
return 0;
}
int n = height.length;
int res = 0;
// 数组充当备忘录
int[] l_max = new int[n];
int[] r_max = new int[n];
// 初始化 base case
l_max[0] = height[0];
r_max[n - 1] = height[n - 1];
// 从左向右计算 l_max
for (int i = 1; i < n; i++)
l_max[i] = Math.max(height[i], l_max[i - 1]);
// 从右向左计算 r_max
for (int i = n - 2; i >= 0; i--)
r_max[i] = Math.max(height[i], r_max[i + 1]);
// 计算答案
for (int i = 1; i < n - 1; i++)
res += Math.min(l_max[i], r_max[i]) - height[i];
return res;
}
}
还有一种更优的解法就是双指针解法,思路基本上和上面一样,边遍历边找最大值,代码放下面。
2.2 java版代码示例
class Solution {
public int trap(int[] height) {
if (height.length == 0) {
return 0;
}
//int n = height.length;
int res = 0;
int l_max=0,r_max=0;
int left=0,right=height.length-1;
while(left<right){
l_max=Math.max(l_max,height[left]);
r_max=Math.max(r_max,height[right]);
if(l_max<r_max){
res+=l_max-height[left];
left++;
}else{
res+=r_max-height[right];
right--;
}
}
return res;
}
}