RainWater { public static long findAccumulatedWater(int[] terrain) { if (terrain == null) { return 0; } int maxIndex = 0; long totalWater = 0; long tempWater = 0; for (int index = maxIndex + 1; index < terrain.length; index++) { if (terrain[index] >= terrain[maxIndex]) { totalWater += tempWater; tempWater = 0; maxIndex = index; } else { tempWater += terrain[maxIndex] - terrain[index]; } } tempWater = 0; int reverseMaxIndex = terrain.length - 1; for (int index = reverseMaxIndex - 1; index >= maxIndex; index--) { if (terrain[index] >= terrain[reverseMaxIndex]) { totalWater += tempWater; tempWater = 0; reverseMaxIndex = index; } else { tempWater += terrain[reverseMaxIndex] - terrain[index]; } } return totalWater; }  static long findAccumulatedWater(int[] terrain);  }
@Test public void findAccumulatedWater_NoWaterAccumulated() { assertEquals(0L, RainWater.findAccumulatedWater(new int[] { 2, 1 })); }
@Test public void findAccumulatedWater_SomeWaterAccumulated() { assertEquals( 25L, RainWater.findAccumulatedWater(new int[] { 2, 0, 2, 1, 3, 2, 6, 0, 5, 2, 10, 5, 5, 0, 0, 2, 4 })); }