“即使到不了远方,心中也要有远方的模样。”

这题基本上和昨天总结的两个题思路是一模一样的,区别不同的就是,这是一个循环数组,那就直接将两个数组链接就好了。昨天的–>点这里
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 stack = new LinkedList();//用Deque也能做单调栈// Stack stack= new Stack<>();// stack.push(0);for(int i=0;iwhile(!stack.isEmpty()&&(nums[i%len]>nums[stack.peek()])){result[stack.pop()]=nums[i%len];}stack.push(i%len);}return result;
}
}

这题首先拿着可能不好分析,那么就先光看局部,从局部分析,判断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;iint l_max=0,r_max=0;//求i右边的最大值for(int j=i;jl_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 casel_max[0] = height[0];r_max[n - 1] = height[n - 1];// 从左向右计算 l_maxfor (int i = 1; i < n; i++)l_max[i] = Math.max(height[i], l_max[i - 1]);// 从右向左计算 r_maxfor (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;}
}
还有一种更优的解法就是双指针解法,思路基本上和上面一样,边遍历边找最大值,代码放下面。
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(leftl_max=Math.max(l_max,height[left]);r_max=Math.max(r_max,height[right]);if(l_maxres+=l_max-height[left];left++;}else{res+=r_max-height[right];right--;}}return res;}
}
下一篇:什么是死亡?死亡年龄是多少?