【转】有趣的积水问题(Twitter编程面试题)

本文介绍了一道Twitter面试题——水沟积水问题,并提供了一个仅需一次遍历的高效解决方案。该算法通过双指针法计算出给定数组中能够容纳的最大水量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下内容来自转载:

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值