题解 | #容器盛水问题#

容器盛水问题

http://www.nowcoder.com/practice/f92929ec6e5642a690e7c197b0c40e38

/*方法1       时间复杂度O(N^2)
    i位置上方的水= max{min{i左侧最大值,i右侧最大值}-arr[i],0}
    * */
    public static int getWater1(int[] arr) {
        if (arr == null || arr.length < 3) {
            return 0;
        }
        int res = 0;
        for (int i = 1; i < arr.length - 1; i++) {
            int leftMax = 0;
            int rightMax = 0;
            for (int j = 0; j < i; j++) {
                leftMax = Math.max(arr[j], leftMax);
            }
            for (int j = i + 1; j < arr.length; j++) {
                rightMax = Math.max(arr[j], rightMax);
            }

            res += Math.max(Math.min(leftMax, rightMax) - arr[i], 0);
        }
        return res;
    }

    /*方法2:把左右侧最大值存起来
    时间复杂度O(N)   空间复杂度O(N)
    * */
    public static int getWater2(int[] arr) {
        if (arr == null || arr.length < 3) {
            return 0;
        }

        int[] leftMaxs = new int[arr.length];
        leftMaxs[0] = arr[0];
        for (int i = 1; i < arr.length; i++) {
            leftMaxs[i] = Math.max(leftMaxs[i - 1], arr[i]);
        }
        int[] rightMaxs = new int[arr.length];
        rightMaxs[arr.length - 1] = arr[arr.length - 1];
        for (int i = arr.length - 2; i >= 0; i--) {
            rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
        }

        int res = 0;
        for (int i = 1; i < arr.length - 1; i++) {
            res += Math.max(Math.min(leftMaxs[i - 1], rightMaxs[i + 1]) - arr[i], 0);
        }
        return res;
    }

    /*方法3:时间复杂度O(N)     空间复杂度O(1)
    左右指针L   R
    leftMax表示[0...L-1]中的最大值     rightMax表示[R+1....N-1]中的最大值
    * */
    public static int getWater3(int[] arr) {
        if (arr == null || arr.length < 3) {
            return 0;
        }
        int res = 0;
        int leftMax = arr[0];
        int rightMax = arr[arr.length - 1];
        int L=1;
        int R=arr.length-2;
        while (L<=R){
            if(leftMax<=rightMax){
                res+=Math.max(0,leftMax-arr[L]);
                leftMax=Math.max(leftMax,arr[L]);
                L++;
            }else {
                res+=Math.max(0,rightMax-arr[R]);
                rightMax=Math.max(rightMax,arr[R]);
                R--;
            }
        }

        return res;
    }

    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int[] nums=new int[n];
        for (int i = 0; i <n ; i++) {
            nums[i]=in.nextInt();
        }

        int res=getWater3(nums);
        System.out.println(res);
    }
全部评论

相关推荐

10-09 00:50
已编辑
长江大学 算法工程师
不期而遇的夏天:1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
过往烟沉:我说什么来着,java就业面就是广!
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务