• 单调栈: 接雨水


     解法: 雨水面积 = 底边长w*雨水高度h

    双指针:

    • 求每个位置的水位高度,以当前位置为中心,双指针分别向左右寻找最高边界。
    • h = min(lHeight, rHeight) - height[i]; w=1

    动态规划:

    • 根据已知的边界高度和当前高度比较,确定当前位置的左右边界高度,取最高的左右高度值
    • int[len+2][2]: 存放个位置的左边界高,右边界高;首尾设置虚拟节点表示边界,高度为0
    • 遍历高度:左到右确定左界值。右到左确定右界值
    • h = min(lHeight, rHeight) - height[i]; w=1

    单调栈:

    • 栈内元素对应高度值:大到小(栈底到栈头),即栈内可确定左边界(栈内存放下标)
    • 新加元素 符合 单调性:直接加入
    • 新加元素 = 栈头旧元素: 旧元素出栈,新元素入栈 (保证左侧的最右边边界)
    • 新加元素 > 栈头旧元素:右边界确定,栈头出栈,当前栈头为左边界,计算当前凹槽高度的存水量,重复该步骤,直到满足新元素入栈条件
    • 宽(下标间距离)*高(可存高度差):(i-pre-1)*(Math.min(height[i],height[pre])-height[cur])
    1. //双指针法:寻找每个位置上的可堆积的雨水高度,即左右寻找水桶的最高边界,取最低值-底部高度
    2. class Solution {
    3. public int trap(int[] height) {
    4. int sum= 0;
    5. //计算每一个位置可堆积的雨水高度,叠加
    6. int lheight, rheight;
    7. for(int i = 0; i < height.length; i++){
    8. lheight = 0;
    9. rheight = 0;
    10. for(int l = i-1; l >= 0; l--){
    11. lheight = Math.max(lheight,height[l]);
    12. }
    13. for(int r = i+1; r < height.length; r++){
    14. rheight = Math.max(rheight,height[r]);
    15. }
    16. int get = Math.min(lheight,rheight)-height[i];
    17. sum += get>0? get:0;
    18. }
    19. return sum;
    20. }
    21. }
    22. //动态规划:最快,按列计算存水量
    23. class Solution {
    24. public int trap(int[] height) {
    25. int len = height.length;
    26. int[][] dp = new int[len+2][2];//初始值全为0,首尾添加虚拟节点可存水高度一定为0
    27. int sum= 0;
    28. for(int left = 1; left <= len; left++){
    29. dp[left][0] = Math.max(dp[left-1][0],height[left-1]);//左侧高度
    30. int right = len+2-1-left;
    31. dp[right][1] = Math.max(dp[right+1][1],height[right-1]);//右侧高度
    32. }
    33. for(int i = 1; i <= len; i++){
    34. int get = Math.min(dp[i][0],dp[i][1])-height[i-1];
    35. sum += get>0?get:0;
    36. }
    37. return sum;
    38. }
    39. }
    40. //单调栈:按行计算存水量
    41. class Solution {
    42. public int trap(int[] height) {
    43. Stack<Integer> index = new Stack<>();
    44. int sum = 0;
    45. index.push(0);
    46. for(int i = 1; i < height.length; i++){
    47. int cur = index.peek();
    48. while(!index.isEmpty() && height[i] >= height[cur]){
    49. cur = index.pop();
    50. if(!index.isEmpty()){
    51. int pre = index.peek();
    52. sum += (i-pre-1)*(Math.min(height[i],height[pre])-height[cur]);
    53. cur = pre;
    54. }
    55. }
    56. index.push(i);
    57. }
    58. return sum;
    59. }
    60. }

  • 相关阅读:
    Linux网络编程系列之UDP广播
    docker mysql 主从配置
    双飞翼布局
    SpringCloud -- Nacos配置管理
    CoordinatorLayout/AppBarLayout记录滚动位置异常问题
    静态代码块
    C++设计模式_05_Observer 观察者模式
    用护眼灯到底好不好?好用热门的护眼台灯推荐
    RN:Error: /xxx/android/gradlew exited with non-zero code: 1
    英语体系----词根词缀等----持续补充(词根词缀等,词汇,语法,简单句,长难句,写作)
  • 原文地址:https://blog.csdn.net/habe33/article/details/126606731