leetcode42 数组容器问题

问题描述

leetcode42 接雨水 

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

将数组的大小当作是木板的高度,这样一个高低不一的板子竖着放,能放多少水?

解决思路

我的思路很简单,就是按照需要找到凹形状的区域的首位索引,将所有凹形状的盛水量。加起来即可。

*    一遍循环,从头开始遍历,寻找值不小于当前元素的索引
* 如果有,则计算这一段凹形状的盛水量,i 挪到该形状的末尾处
* 如果没有,则则找出当前位置 后面元素中的所出现的最后一个最大值。为什么要最后一个出现的,其实是为了
* 节省时间,画个图来看就知道了。i 继续挪到该凹形状的末尾处
* 如果上述情况都不符合,则 i 自增。

这个简单的思路居然还超过了99的人。。果然最基础的就是最完美的。。。。。。

代码呈现

 1 public class Solution {
 2     public static int trap(int[] height) {
 3         if (height.length==0) { return 0;}
 4         int res = 0;
 5         int i=0;
 6         while ( i < height.length ) {
 7             int findFlag = findBig(height, i);
 8             int next = findSmall(height, i);
 9             if (findFlag > 0) {
10                 System.out.println("i:"+i);
11                 System.out.println("j:"+findFlag);
12                 System.out.println();
13                 res += helper(height, i, findFlag);
14                 i = findFlag;
15             } else if (next > 0) {
16                 res += helper(height, i, next);
17                 i =next;
18             } else { i++; }
19         }
20         return res;
21     }
22 
23     private static int helper(int[] nums, int left, int right) {
24         /*
25          * 计算这一凹形状的盛水量。
26          */
27         int curSum = nums[left] < nums[right] ? nums[left] : nums[right];
28         curSum = curSum * (right-left-1);
29         for (int i = left+1; i<right; i++) {
30             curSum -= nums[i];
31         }
32         return curSum;
33     }
34 
35     private static int findBig(int[] nums, int start) {
36         /*
37          * 在当前元素后面找到不小于当前元素的下标。有,则返回。无,则返回 -1。
38          */
39         for (int i=start+1; i<nums.length; i++) {
40             if (nums[i] >= nums[start]) { return i; }
41         }
42         return -1;
43     }
44 
45     private static int findSmall(int[] nums, int start) {
46         /*
47          * 如果当前元素比后面所有都要大,则找出当前位置 后面元素中的所出现的最后一个最大值。
48          */
49         if (start+1<nums.length) {
50             int max=nums[start+1];
51             int index = start+1;
52             for(int i = nums.length-1; i>start; i--) {
53                 if (nums[i] > max) {
54                     max = nums[i];
55                     index = i;
56                 }
57             }
58             if (index == start +1) {
59                 return -1;
60             }
61 
62             return index;
63         }
64 
65         return -1;
66     }
67 }

在看了标准答案后,发现自己的思路虽然简单,但是代码量就有点大了。答案给了三种解法:动态规划、左右指针、栈方法。

其中栈方法自己应该想出来的。可惜了,但是这几种方法虽然代码简洁,但是思考起来还是很困难。

栈方法解法如下:

 1 class Solution {
 2     public int trap(int[] height) {
 3         if (height == null || height.length == 0) return 0;
 4         Deque<Integer> stack = new ArrayDeque<>();
 5         int res = 0;
 6         for (int i = 0; i < height.length; i++){
 7             while ( ! stack.isEmpty() && height[stack.peek()] < height[i]) {
 8                 int tmp = stack.pop();
 9                 if (stack.isEmpty()) break;
10                 res += (Math.min(height[i],height[stack.peek()]) - height[tmp]) * (i - stack.peek() - 1);
11             }
12             stack.push(i);
13         }
14         return res;
15     }
16 }

猜你喜欢

转载自www.cnblogs.com/dogeLife/p/11061772.html