1. 程式人生 > >【轉】有趣的積水問題(Twitter程式設計面試題)

【轉】有趣的積水問題(Twitter程式設計面試題)

以下內容來自轉載:

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));  
    }  
}