classSolution{ publicinttrap(int[] height){ /** * 当前列可以承载的雨滴数= min(当前列左右两侧的最大值)-当前列的大小; * 就是当前这个列的左边最高列和右边最高列中的最小那个 与 本列的差值 是否大于>0 */ int sum = 0; int[] left = newint[height.length]; int[] right = newint[height.length]; for (int i = 1; i < height.length - 1; i++) { left[i] = Math.max(left[i - 1], height[i - 1]); } for (int i = height.length - 2; i >= 0; i--) { right[i] = Math.max(right[i + 1], height[i + 1]); } for (int i = 1; i < height.length - 1; i++) { int min = Math.min(left[i], right[i]); if (min > height[i]) { sum = sum + min - height[i]; } } return sum; } }
方法二:双指针
可以看到,left [ i ] 和right [ i ] 数组中的元素只用一次。所以我们可以只用一个元素代替。例如第一个循环和第三个for循环的方向是一样的,于是可以定义一个max_left来代替left[i]。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicinttrap(int[] height){ int sum = 0; int max_left = 0; int[] right = newint[height.length]; for (int i = height.length - 2; i >= 0; i--) { right[i] = Math.max(right[i + 1], height[i + 1]); } for (int i = 1; i < height.length - 1; i++) { max_left = Math.max(max_left, height[i - 1]) int min = Math.min(max_left, right[i]); if (min > height[i]) { sum = sum + min - height[i]; } } return sum; }
publicinttrap(int[] height){ int sum = 0; int max_left = 0; int max_right = 0; int left = 1, right = height.length - 2; for (int i = 1; i < height.length - 1; i++) { if (height[left - 1] < height[right + 1]) { max_left = Math.max(max_left, height[left - 1]) int min = max_left; if (min > height[left]) { sum = sum + min - height[left]; } left++; } else { max_right = Math.max(max_right, height[right + 1]) int min = max_right; if (min > height[right]) { sum = sum + min - height[right]; } right--; } } return sum; }