题解 | #容器盛水问题#

容器盛水问题

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个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务