leetCode Trapping Rain Water
来源:互联网 发布:js给select option赋值 编辑:程序博客网 时间:2024/05/16 15:01
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; }
阅读全文
0 0
- LeetCode: Trapping Rain Water
- LeetCode : Trapping Rain Water
- [LeetCode] Trapping Rain Water
- [Leetcode] Trapping Rain Water
- [Leetcode] Trapping Rain Water
- [LeetCode]Trapping Rain Water
- LeetCode-Trapping Rain Water
- [leetcode] Trapping Rain Water
- [LeetCode] Trapping rain water
- Leetcode: Trapping Rain Water
- Leetcode:Trapping Rain Water
- [LeetCode] Trapping Rain Water
- <Leetcode>Trapping Rain Water
- Leetcode Trapping Rain Water
- leetcode Trapping Rain Water
- leetcode Trapping Rain Water
- LeetCode Trapping Rain Water
- LeetCode | Trapping Rain Water
- ZooKeeper的安装与部署
- 翻转子串
- 【不用加减乘除做加法】
- jQuery随笔
- Android 沉浸式状态栏实现攻略(一)
- leetCode Trapping Rain Water
- 1049. 数列的片段和(20)
- 终极方案:webview 闪白屏问题
- 手机自动化工具monkey软件位置
- 回家 Bessie Come Home
- Docker 自修笔记(一)
- 你传输的数据有没有被恶意篡改?
- COJ: A-SUM(贪心)
- 1059. C语言竞赛(20)