[leetcode]42. Trapping Rain Water
阿新 • • 發佈:2018-12-08
我這個腦子哦,暴力和動態規劃都有點思路,然後就是想不全。
想複雜了,一個一個高度減不就好了,我在那裡總面積減。
下面幾種方法都是一個一個豎的小面積算的。
Solution 1:暴力解法
時間複雜度o(n*n)
空間複雜度o(1)
從i往兩邊找最大
class Solution { public int trap(int[] height) { if(height==null||height.length==0)return 0; int area=0; for(int i=1;i<height.length-1;i++){ int maxheightleft=height[i]; int maxheightright=height[i]; int k=1; while(i-k>=0){ if(height[i-k]>=maxheightleft){ maxheightleft=height[i-k]; } k++; } k=1; while(i+k<height.length){ if(height[i+k]>=maxheightright){ maxheightright=height[i+k]; } k++; } area+=Math.min(maxheightleft,maxheightright)-height[i]; } return area; } }
Solution 2:動態規劃
時間和空間複雜度都是o(n)
class Solution { public int trap(int[] height) { if(height==null||height.length==0)return 0; int ans = 0; int size = height.length; int[] left_max=new int[size]; int[] right_max=new int[size]; left_max[0] = height[0]; for (int i = 1; i < size; i++) { left_max[i] = Math.max(height[i], left_max[i - 1]); } right_max[size - 1] = height[size - 1]; for (int i = size - 2; i >= 0; i--) { right_max[i] = Math.max(height[i], right_max[i + 1]); } for (int i = 1; i < size - 1; i++) { ans += Math.min(left_max[i], right_max[i]) - height[i]; } return ans; } }
Solution 3: 使用堆疊
這個只能畫圖理解了。是從下到上一層一層加的。
例如[5,2,1,2,1,5]
是先算凹下去的兩個1,再算一個0,再算上面的4*3=12,一共是14。
時間和空間複雜度都是o(n)
class Solution { public int trap(int[] height) { int ans=0; int current=0; Stack<Integer> st=new Stack<Integer>(); while(current<height.length){ while(!st.empty()&&height[current]>height[st.peek()]){ int mid=st.peek(); st.pop(); if(st.empty())break; int left=st.peek(); int distance=current-left-1; int bounded_height = Math.min(height[current], height[left] - height[mid]); ans+=distance*bounded_height; } st.push(current++); } return ans; } }
Solution 4: 最後一種 two pointer。感覺太難想了
如果左邊小於右邊,則從左到右加
反之
如果左邊大於右邊,則從右到左加
int trap(vector<int>& height)
{
int left = 0, right = height.size() - 1;
int ans = 0;
int left_max = 0, right_max = 0;
while (left < right) {
if (height[left] < height[right]) {
height[left] >= left_max ? (left_max = height[left]) : ans += (left_max - height[left]);
++left;
}
else {
height[right] >= right_max ? (right_max = height[right]) : ans += (right_max - height[right]);
--right;
}
}
return ans;
}