【轉】有趣的積水問題(Twitter程式設計面試題)
阿新 • • 發佈:2018-12-09
以下內容來自轉載:
Twitter面試題:水溝積水問題
問題描述:“看下面這個圖片”
“在這個圖片裡我們有不同高度的牆。這個圖片由一個整數陣列所代表,陣列中每個數是牆的高度。上邊的圖可以表示為陣列[2,5,1,2,3,4,7,7,6]”
“假如開始下雨了,那麼牆之間的水坑能夠裝多少水呢?”
思路分析: 一種只需要一次遍歷的方法(注:不知道算不算動態規劃演算法,請知道的高人鑑定一下)
1. 首先,用兩個指標(left 和 right)分別指向陣列的第一個元素和最後一個元素,左指標從左向右遍歷,右指標從右向左遍歷;
2. 初始化陣列中一個元素(a[0])為左邊遍歷得到的最大值(max_left),最後一個元素(a[a.length-1])為從右邊遍歷得到的最大值(max_right);
3. 開始遍歷,遍歷條件為左指標小於右指標
4. 如果左邊遍歷的最大值小於右邊遍歷的最大值,說明只要有水溝(即小於左邊最大值max_left的元素)就會有積水,因為右邊的最大值可以保證左邊水溝的積水不會流失掉;
同樣,如果左邊遍歷的最大值不小於右邊遍歷的最大值,只要右邊有水溝(即小於右邊最大值max_right的元素)就會有積水。
解決方案:Java實現程式碼
public class Twitter_puddle { public int caculate(int[] a) { if (a == null) return 0; int left = 0; int right = a.length - 1; int max_left = a[left]; int max_right = a[right]; int volume = 0; while (left < right) { if (max_left < max_right) { left++; if (max_left < a[left]) { max_left = a[left]; } else { volume += max_left - a[left]; } } else { right--; if (max_right < a[right]) { max_right = a[right]; } else { volume += max_right - a[right]; } } } return volume; } }
測試程式碼
import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import static org.hamcrest.Matchers.*; public class Twitter_puddleTest { private Twitter_puddle puddle; @Before public void before() { puddle = new Twitter_puddle(); } @Test public void testNull() { assertThat(puddle.caculate(null), is(0)); } @Test public void testOne() { int a[] = {1}; assertThat(puddle.caculate(a), is(0)); } @Test public void testTwoRightHigher() { int a[] = {1, 2}; assertThat(puddle.caculate(a), is(0)); } @Test public void testTwoLeftHigher() { int a[] = {2, 1}; assertThat(puddle.caculate(a), is(0)); } @Test public void testTwoSameHight() { int a[] = {1, 1}; assertThat(puddle.caculate(a), is(0)); } @Test public void testThreeMiddleHigher() { int a[] = {1, 2, 1}; assertThat(puddle.caculate(a), is(0)); } @Test public void testThreeMiddleLower() { int a[] = {2, 1, 2}; assertThat(puddle.caculate(a), is(1)); } @Test public void testThreeSameHeight() { int a[] = {1, 1, 1}; assertThat(puddle.caculate(a), is(0)); } @Test public void testRandom1() { int a[] = {2, 5, 1, 2, 3, 4, 7, 7, 6}; assertThat(puddle.caculate(a), is(10)); } @Test public void testRandom2() { int a[] = {2, 5, 1, 3, 1, 2, 1, 7, 7, 6}; assertThat(puddle.caculate(a), is(17)); } @Test public void testRandom3() { int a[] = {6, 1, 4, 6, 7, 5, 1, 6, 4}; assertThat(puddle.caculate(a), is(13)); } @Test public void testRandom4() { int a[] = {6, 6, 6, 6, 6, 6, 6, 6, 6}; assertThat(puddle.caculate(a), is(0)); } }