• 42. Trapping Rain Water


    一、题目

      1、审题

      2、分析:

        给出一组整数坐标,代表在 x 轴上的单位为1的木块的高度,求得这些木块之间最多可以积多少水。

    二、解答

      1、思路:

        方法一:a、求出最高的木块的高度,记其下标为 index;

            b、求 index 左方最高木块的下标, secondIndex;并可以求出 secondIndex 与 index 之间的积水;

            c、令 index = secondIndex,循环求出 index 左方的全部积水, 当 index = 0 时跳出循环;

            d、同理可求 index 右方积水。

      

    public class Solution {
        public int trap(int[] height) {
            int end = height.length - 1;
            if( end < 2) return 0;
            
            int index = findMaxNumberIndex(height, 0, end);
            
            int result = 0;
            int i = index, j = index;
            
            while(i != 0) {
                
                int secondIndex = findMaxNumberIndex(height, 0, i-1);
                result += countMediumWater(height, secondIndex, i);
                i = secondIndex;
            }
            while (j != end) {
                int secondIndex = findMaxNumberIndex(height, j+1, end);
                result += countMediumWater(height, j, secondIndex);
                j = secondIndex;
            }
            
            System.out.println(result);
            return result;
        }
    
        private int findMaxNumberIndex(int[] height, int start, int end) {
            int index = start;
            for (int i = start + 1; i <= end; i++) {
                if(height[i] > height[index]) {
                    index = i;
                }
            }
            return index;
        }
    
        private int countMediumWater(int[] height, int start, int end) {
            
            if(start == end - 1) return 0;
            int block = 0;
            for (int i = start+1; i < end; i++) 
                block += height[i];
            int result = Math.min(height[start], height[end]) * (end-start-1) - block; 
            return result;
        }
    }

      方法二、a、 定义两个指针,left 指向 0,向右移动; right 指向数组最后一个元素,向左移动;

          b、定义3个变量, leftMax代表 left 向右移动时的木块最高长度,rightMax 代表 right向左移动时的最高长度,max 代表积水量;

          c、当 left <= right 时进行循环,

              若 leftMax < rightMax 时, max += leftMax - height[left++]; 

              否则 max += rightMax - height[right--];

          意思是,取最左边与最右边的短板,若左边为短板,则计算左边短板与当前遍历的左边下标板块的积水量。否则计算右边短板与当前的右边下标的积水量。

           

    public int trap(int[] height) {
            int max = 0;
            int leftMax = 0;
            int rightMax = 0;
            int left = 0;
            int right = height.length - 1;
            
            while(left <= right) {
                leftMax = Math.max(leftMax, height[left]);
                rightMax = Math.max(rightMax, height[right]);
                
                if(leftMax <= rightMax) 
                    max += leftMax - height[left++];
                else 
                    max += rightMax - height[right--];
            }
            
            return max;
        }
  • 相关阅读:
    最长公共子序列-动态规划
    归并排序
    最大子段和-3种方法
    kafka compaction 分析(基于kafka 0.10.2版本)
    [转载]interp1
    [转]mat2gray函数原理分析
    Java 位运算(移位、位与、或、异或、非)与逻辑运算
    ML01a
    [第1集] 机器学习的动机与应用
    tap4fun公司面试总结
  • 原文地址:https://www.cnblogs.com/skillking/p/9602699.html
Copyright © 2020-2023  润新知