leetCode Trapping Rain Water
2017-07-14 12:24
435 查看
1、观察图形,能积水的部分一定是两个塔顶之间,所以可以先找到所有的塔顶list,再算它们之间积水
2、首先找到list最高的两个塔顶firHigh,secHigh,那么它们之间的积水一定是两个顶之间较低的那个sum(secHigh-height[i])。然后可以把list中firHigh,secHigh之间的塔顶拿掉
3、然后再找剩下的塔顶里面最高的highpos,如果highpos在以计算区间左边,那就计算左边新增区间面积,否则就是右边的。
public int trap(int[] height) { int count=0; if(height == null || height.length<3)return 0; int len = height.length; List<Integer> list = new ArrayList<Integer>(); if(height[0]>height[1])list.add(0); for(int i=1;i<len-1;i++) if(height[i]>=height[i-1]&&height[i]>=height[i+1]) list.add(i); if(height[len-1]>height[len-2]) list.add(len-1); if(list.size()<2)return 0; //拿到了所有高点位置 //Collections.sort(list,Collections.reverseOrder()); int firstHighPos=-1,firstHigh=-1; int secHighPos=-1,secHigh=-1; for(int i=0;i<list.size();i++){ if(firstHigh==-1){ firstHighPos=list.get(i); firstHigh = height[firstHighPos]; } else if(height[list.get(i)]>firstHigh){ secHighPos=firstHighPos; secHigh = firstHigh; firstHighPos=list.get(i); firstHigh = height[firstHighPos]; } else if(height[list.get(i)]>secHigh){ secHighPos=list.get(i); secHigh = height[secHighPos]; } } //list里面是存的位置 int leftPos= -1; int rightPos=-1; if(firstHighPos<secHighPos){ leftPos= firstHighPos; rightPos=secHighPos; } else{ leftPos=secHighPos ; rightPos=firstHighPos; } //清掉list中left、right之间的pos,不需要了 for(int i=list.size()-1;i>=0;i--){ if(list.get(i)<=rightPos&&list.get(i)>=leftPos ){ list.remove(i); } } count+=cal(height, leftPos,rightPos); while(list.size()>0){ int HighPos=-1,High=-1; for(int i=0;i<list.size();i++){ if(height[list.get(i)]>High){ HighPos=list.get(i); High = height[list.get(i)]; } } //更新已计算pos范围 if(HighPos<leftPos){ count+=cal(height, HighPos,leftPos); leftPos = HighPos; } else{ count+=cal(height, rightPos,HighPos); rightPos = HighPos; } //清掉list中left、right之间的pos,不需要了 for(int i=list.size()-1;i>=0;i--){ if(list.get(i)<=rightPos&&list.get(i)>=leftPos ){ list.remove(i); } } } return count; } public static int cal(int[] height,int leftPos,int rightPos){ int count=0; int min = height[leftPos]<height[rightPos]?height[leftPos]:height[rightPos]; for(int j=leftPos+1;j<rightPos;j++){ count+=min-height[j]>0?min-height[j]:0; } return count; }
这种想法比较自然,扫描height也只要O(n),不过需要使用list记录塔顶位置,有额外开销
看了下别人的思路,有一种比较简单,记录每个位置左边最大的高度lefthigh和右边最大的高度righthigh,那么area[i]=min(lefthigh,righthigh)-height[i]
所以只需要扫描height三遍,分别计算出lefthigh[i]和右边最大的高度righthigh[i]和area[i]即可
public int trap(int[] height) { int count=0; if(height == null || height.length<3)return 0; int len = height.length; int left = 0; int right = len-1; int max=0; int A[]=new int[len]; int B[]=new int[len]; while(left<len){ if(height[left]>max){ max=height[left]; } A[left]=max; left++; } max=0; while(right>-1){ if(height[right]>max){ max=height[right]; } B[right]=max; right--; } for(int i=0;i<len;i++){ if(A[i]>B[i]) count+=B[i]-height[i]; else count+=A[i]-height[i]; } return count; }
相关文章推荐
- LeetCode | Trapping Rain Water
- [Leetcode] Trapping Rain Water
- [leetCode]Trapping Rain Water
- 【leetcode】Trapping Rain Water
- [LeetCode]Container With Most Water、Trapping Rain Water
- [leetcode] Trapping Rain Water
- LeetCode Trapping Rain Water
- leetCode_Trapping Rain Water
- leetcode[42]Trapping Rain Water
- leetcode hard模式专杀之42. Trapping Rain Water
- Leetcode NO.42 Trapping Rain Water
- [leetcode]Trapping Rain Water
- leetcode Trapping Rain Water
- 【题解】【直方图】【Leetcode】Trapping Rain Water
- leetcode;Trapping Rain Water
- Leetcode Trapping Rain Water
- [Leetcode 42, Hard] Trapping Rain Water
- leetcode--Trapping Rain Water
- LeetCode(42)--Trapping Rain Water
- LeetCode Online Judge 题目C# 练习 - Trapping Rain Water