存水问题 (TwoPoint)

题目描述

存水问题 (TwoPoint)_第1张图片
2.PNG

[leetcode42] https://leetcode.com/problems/trapping-rain-water/

思考某一个位置,其能存下水的本质是其左边最大值和右边最大值与当前数的差(值大于0就表明当前位置可以存下水)

思路

那么接下来就有这么几个思路:

  1. 在i位置遍历左边右边求左最大和右最大。O(n^2)
  2. 使用两个数组,一个数组记录左最大[0,i),一个数组记录右最大(i,n-1]。遍历两遍即可知道,然后求water[i]即可。O(n)
  3. 最最大数组没有必要再求,用一个变量记录左边最大,省去左边这个数组。O(n)
  4. (先找到可能的最大值,然后看哪些位置的水可以被算出来)
    5,4,,,3,7 ->4的水量可以确定
    前三种就不贴代码了,看一下方法4

算法四 O(n)time O(1)space

算法步骤

  1. 使用四个变量,leftMax:左边最大 rightMax:右边最大 ,两指针left,right。一个变量water记录水量。
  2. 两指针开始走,首先看laftMax和rightMax,哪边小,证明哪边就可以结算,处理那边的那个位置的水量,同时更新位置和最值。

代码

public class Solution {
    public int trap(int[] height) {
        if(height==null||height.length<3)
            return 0;
        int leftMax=height[0];
        int rightMax=height[height.length-1];
        int left=1;
        int right=height.length-2;
        int water=0;
        while(left<=right){
            if(leftMax

算法五 O(n)time O(1)space

算法步骤

  1. 遍历数组,求出最大值所在位置
  2. 分别对最大值所在位置的左边和右边求解,求解左边的时候,记录一个左边最大,然后遍历左半部分,如果当前位置小于左最大,那么当前位置可以存水,否则更新左最大。右边同理。

算法原理

为什么可以这么做?因为寻找了最大位置,这个位置的存在就作为了左边和右边的保障,例如对于最大值左边的元素来说,你只需要知道这些元素左边的最大是多少就行了,因为对该位置存水量有限制的就是左边最大,因为他的右边最大就是全局最大,我们拥有这个保障。

代码

    public int trap(int[] height) {
        if(height==null||height.length<3)
            return 0;
        int max=0,maxIndex=0;
        for(int i=0;imax)
            {
                max=height[i];
                maxIndex=i;
            }
        }
        int area=0;
        int left=0;
        for(int i=0;imaxIndex;i--){
           if(height[i]

你可能感兴趣的:(存水问题 (TwoPoint))