• 刷题笔记:对撞型/相会型指针(1) 灌水类


    1 Trapping Rain Water  

    Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
    For example,
    Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
    The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.Thanks Marcos for contributing this image!
    » Solve this problem

    [解题思路]
    对于任何一个坐标,检查其左右的最大坐标,然后相减就是容积。所以,
    1. 从左往右扫描一遍,对于每一个坐标,求取左边最大值。
    2. 从右往左扫描一遍,对于每一个坐标,求最大右值。
    3. 再扫描一遍,求取容积并加和。
    #2和#3可以合并成一个循环,

     
    扫描3遍数组的方法:
    public class Solution {
        public int trap(int[] height) {
            if (height == null || height.length == 0) {
                return 0;
            }
            int len = height.length;
            int res = 0;
            int[] leftMax = new int[len];
            int[] rightMax = new int[len];
            leftMax[0] = height[0];
            rightMax[len - 1] = height[len - 1];
            for (int i = 1; i < len; i++) {
                leftMax[i] = Math.max(leftMax[i - 1], height[i]);
            }
            for (int i = len - 2; i >= 0; i--) {
                rightMax[i] = Math.max(rightMax[i + 1], height[i]);
            }
            for (int i = 1; i < len - 1; i++) {
                int amount = Math.min(leftMax[i - 1], rightMax[i + 1]) - height[i];
                if (amount > 0) {
                    res += amount;
                }
            }
            return res;
        }
    }
    View Code

    可以简化为对撞型指针,扫描1遍数组,总体思想类似

    其实可以看作是一个动态规划的滚动数组优化,把leftMax, rightMax优化为o(1)变量

    public class Solution {
        public int trap(int[] height) {
            if (height == null || height.length < 3) {
                return 0;
            }   
            int len = height.length;
            int leftHeight = height[0];
            int rightHeight = height[len - 1];
            int left = 0;
            int right = len - 1;
            int res = 0;
            
            while (left < right) {
                if (height[left] < height[right]) {
                    if (leftHeight > height[left]) {
                        res += leftHeight - height[left];
                    } else {
                        leftHeight = height[left];
                    }
                    left++;
                } else {
                    if (rightHeight > height[right]) {
                        res+= rightHeight - height[right];
                    } else {
                        rightHeight = height[right];
                    }
                    right--;
                }
            } // end of left < right
            return res;
        }
    }
    trap

    2. //todo

  • 相关阅读:
    字符编码及文件处理
    列表、元祖、字典及集合的内置方法
    数字类型、字符串及列表的内置方法
    流程控制(if while for)
    一些基本概念及数据类型
    编程语言的发展及变量
    python 入门基本知识
    叁拾贰(转)
    叁拾壹
    叁拾
  • 原文地址:https://www.cnblogs.com/jiangchen/p/5983252.html
Copyright © 2020-2023  润新知