如果我们把0看做漏水,这个题目的解法该怎么变化呢。首先考虑我们Trapping Rain Water中考虑的第一种dp解法,我们要做变化的就是如果当前是0的话,我们把arr的值也设为0,并且,从左向右扫的时候,如果前一个是0并且当前是递增序列的话,也是没有办法存水的。从右向左扫的时候是类似的。DP方程如下:
- if A[i] == 0, f[i] = 0;
- else if A[i - 1] == 0 && A[i - 1] <= A[i], f[i] = 0;
- else, f[i] = max(f[i - 1], A[i - 1]);
对于第二种解法,没有太好的办法可以用过来,原因是在第一题当中第二种方法我们移动指针的时候可以确保可以存水的,但是当0代表漏水的时候,我们不能保证中间递减的一块还可以存水了,所以双指针方法不好运用过来。
第三种方法,我们可以当check到0的时候,把栈清空,然后坐标移到下一个递减序列的开头,这样就可以。代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TrappingRainWater { | |
public int trapI(int[] A) { | |
if (A == null) | |
return 0; | |
int len = A.length; | |
if (len < 3) | |
return 0; | |
int[] left = new int[len]; | |
int right = 0, sum = 0; | |
for (int i = 1; i < len; i++) { | |
if (A[i] == 0) | |
left[i] = 0; | |
else if (left[i - 1] == 0 && A[i - 1] <= A[i]) | |
left[i] = 0; | |
else | |
left[i] = A[i - 1] >= left[i - 1]? A[i - 1]: left[i - 1]; | |
} | |
for (int i = len - 2; i >= 0; i--) { | |
if (A[i] == 0) | |
right = 0; | |
else if (right == 0 && A[i] >= A[i + 1]) | |
right = 0; | |
else | |
right = A[i + 1] >= right? A[i + 1]: right; | |
int height = left[i] <= right? left[i]: right; | |
int area = A[i] >= height? 0: height - A[i]; | |
sum += area; | |
} | |
return sum; | |
} | |
public int trapII(int[] A) { | |
if (A == null) | |
return 0; | |
int len = A.length; | |
if (len < 3) | |
return 0; | |
Stack<Integer> stack = new Stack<Integer>(); | |
int sum = 0; | |
for (int i = 0; i < len;) { | |
if (A[i] == 0) { | |
while (!stack.isEmpty()) | |
stack.pop(); | |
while (i < len - 1 && A[i] <= A[i + 1]) | |
i++; | |
if (i == len - 1) | |
break; | |
continue; | |
} else { | |
if (!stack.isEmpty() && A[stack.peek()] <= A[i]) { | |
int base = A[stack.peek()]; | |
stack.pop(); | |
while (!stack.isEmpty() && A[stack.peek()] <= A[i]) { | |
sum += (A[stack.peek()] - base) * (i - stack.peek() - 1); | |
base = A[stack.pop()]; | |
} | |
sum += stack.isEmpty()? 0: (A[i] - base) * (i - stack.peek() - 1); | |
} | |
stack.push(i++); | |
} | |
} | |
return sum; | |
} | |
public static void main(String[] args) { | |
test1(); | |
test2(); | |
test3(); | |
test4(); | |
test5(); | |
test6(); | |
test7(); | |
} | |
//test cases | |
public static void test1() { | |
int[] A = {2,0,2}; | |
TrappingRainWater t = new TrappingRainWater(); | |
if (t.trapI(A) == 0 && t.trapII(A) == 0) | |
System.out.println("Test case 1 passed!"); | |
else | |
System.out.println("Test case 1 failed!"); | |
} | |
public static void test2() { | |
int[] A = {0,1,0,2,1,0,1,3,2,1,2,1}; | |
TrappingRainWater t = new TrappingRainWater(); | |
if (t.trapI(A) == 1 && t.trapII(A) == 1) | |
System.out.println("Test case 2 passed!"); | |
else | |
System.out.println("Test case 2 failed!"); | |
} | |
public static void test3() { | |
int[] A = {3,2,1,0,2,3,2,1,3,0,3}; | |
TrappingRainWater t = new TrappingRainWater(); | |
if (t.trapI(A) == 3 && t.trapII(A) == 3) | |
System.out.println("Test case 3 passed!"); | |
else | |
System.out.println("Test case 3 failed!"); | |
} | |
public static void test4() { | |
int[] A = {5,3,1,4,0,1,3,5,6,3,2,3,1}; | |
TrappingRainWater t = new TrappingRainWater(); | |
if (t.trapI(A) == 5 && t.trapII(A) == 5) | |
System.out.println("Test case 4 passed!"); | |
else | |
System.out.println("Test case 4 failed!"); | |
} | |
public static void test5() { | |
int[] A = {32,16,5,7,17,28,0,9,10,11,4,5,22,27,0,2,4,3,2,5}; | |
TrappingRainWater t = new TrappingRainWater(); | |
if (t.trapI(A) == 83 && t.trapII(A) == 83) | |
System.out.println("Test case 5 passed!"); | |
else | |
System.out.println("Test case 5 failed!"); | |
} | |
public static void test6() { | |
int[] A = {0,0,0,0,0,0,0,10,5,4,7,0,10,0,0,0}; | |
TrappingRainWater t = new TrappingRainWater(); | |
if (t.trapI(A) == 5 && t.trapII(A) == 5) | |
System.out.println("Test case 6 passed!"); | |
else | |
System.out.println("Test case 6 failed!"); | |
} | |
public static void test7() { | |
int[] A = {0,0,0,0,0,0,0,10,5,4,7,0,10,0,0,5}; | |
TrappingRainWater t = new TrappingRainWater(); | |
if (t.trapI(A) == 5 && t.trapII(A) == 5) | |
System.out.println("Test case 7 passed!"); | |
else | |
System.out.println("Test case 7 failed!"); | |
} | |
} |
No comments:
Post a Comment