leetcode605

sgq‘s answer:

class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
        int i = 0;
        int num = 0;

        // 找1法
        while(i < flowerbed.length){ // 找flowerbed[i] == 1的点
            if(flowerbed[i] == 1){
                // 这么长,为了解决{1,0,0,0,1,0,0}
                if( (i+2 == flowerbed.length - 1 && flowerbed[i+2] == 0) || i+3 < flowerbed.length && flowerbed[i+2] == 0 && flowerbed[i+3] == 0){
                    num++;
                    flowerbed[i+2] = 1;
                }
            }
            // 将起始位为0的情况考虑进去
            else {
                if(i == 0 && (flowerbed.length == 1 || flowerbed[1] == 0)){ // 解决{0}
                    num++;
                    flowerbed[0] = 1;
                    i--; //解决{0,0,0,0,1}
                }
            }
            i++;
        }


        if(num >= n)return true;
        else return false;
    }
}


class test{
    public static void main(String[] args) {
        int[] flowerbed = {0,0,0,0,1};
        System.out.println(new Solution().canPlaceFlowers(flowerbed, 2));
    }
}

数学归纳法,很简单推出来

统计连续的0的区间,分别有多少个连续的0即可。对于每一段0区间,都可以根据公式直接算出可以种几朵花。

公式可以通过数学归纳法推出来,很简单:

1)对于中间的0区间:

1~2个0:可种0朵;

3~4个:可种1朵;

5~6个:可种2朵;

count个:可种 (count-1)/2 朵

2)对于两头的0区间,由于左边、右边分别没有1的限制,可种花朵数稍有不同。

为了代码流程的统一,可以在数组最左边、数组最右边分别补1个0,意味着花坛左边、右边没有花。

这样公式就跟1)相同了。

Java,1ms,100%

public static boolean canPlaceFlowers(int[] flowerbed, int n) {
if (flowerbed == null || flowerbed.length == 0) return n == 0;

    int countOfZero = 1; // 当前全0区段中连续0的数量,刚开始预设1个0,因为开头花坛的最左边没有花,可以认为存在一个虚无的0
    int canPlace = 0; // 可以种的花的数量
    for (int bed : flowerbed) {
        if (bed == 0) { // 遇到0,连续0的数量+1
            countOfZero++;
        } else { // 遇到1,结算上一段连续的0区间,看能种下几盆花:(countOfZero-1)/2
            canPlace += (countOfZero-1)/2;
            if (canPlace >= n) return true;
            countOfZero = 0; // 0的数量清零,开始统计下一个全0分区
        }
    }
    // 最后一段0区还未结算:
    countOfZero++; // 最后再预设1个0,因为最后花坛的最右边没有花,可以认为存在一个虚无的0
    canPlace += (countOfZero-1)/2;

    return canPlace >= n;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值