跳至主要內容

605-种花问题

daipeng大约 3 分钟

假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给你一个整数数组  flowerbed 表示花坛,由若干 01 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false。

 

示例 1:

输入:flowerbed = [1,0,0,0,1], n = 1
输出:true
示例 2:

输入:flowerbed = [1,0,0,0,1], n = 2
输出:false
 

提示:

1 <= flowerbed.length <= 2 * 104
flowerbed[i]01
flowerbed 中不存在相邻的两朵花
0 <= n <= flowerbed.length
通过次数135,615提交次数412,417

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/can-place-flowers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

错误方法

看完题目后,我首先想到的是假如一个全0的数组,那么最多可以种植多少株花呢? 比如[0,0,0],显然最多可以种植2株,即[1,0,1] [0,0,0,0,0],最多可以种植3株,即[1,0,1,0,1] 所以只要先计算数组最多可以种植的花朵数量,然后减去当前已经种植花朵数量,差值如果小于给定的n,就说明可以种下了。 分分钟写完。

 public boolean canPlaceFlowers(int[] flowerbed, int n) {
 if (n == 0) {
            return true;
        }
        int oneCount = Arrays.stream(flowerbed).filter(k -> k == 1).sum();
        int size = flowerbed.length;
        int total = (size + 1) / 2;
        return n + oneCount <= total;
    }

写完提交发现没有ac,115/124,然后仔细想了想,发现思路是错误的。 因为给定的数组并不一定是按照最优的方法种植的花朵,比如给定数组[0,1,0],那么继续可以种植的花朵实际是0,所以上面思路的问题是没有考虑当前的数组里1的位置,只是按照最乐观的情况进行计算。

模拟算法

老老实实的走模拟的思路,遍历数组,然后在可以种植的位置种上,最后与参数进行比较。 种植的时候注意首尾两个元素需要特殊判断。 这种模拟的方法是符合贪心的思路的,即遍历时候是能种上咱就种上,尽量的多。

public boolean canPlaceFlowers(int[] flowerbed, int n) {
        if (n == 0) {
            return true;
        }
        int size = flowerbed.length;
        if (size == 1) { //先把只包含一个元素这种情况特殊处理下
            return n==1 && flowerbed[0] == 0;
        }
        for (int i = 0; i < flowerbed.length; i++) {
            if(flowerbed[i] == 1){ //如果当前位置已经种植了花,跳过
                continue;
            }
            if (i == 0) { 
                if (flowerbed[i + 1] == 0) { //如果是第0个位置,看看第1个位置是不是0,是0的话就可以种上
                    n--;
                    flowerbed[i] = 1;
                }
            } else if (i == flowerbed.length - 1) {
                if (flowerbed[i - 1] == 0) { //如果是最后一个位置,看下之前的是不是0,如果是0则可以种上
                    n--;
                    flowerbed[i] = 1;
                }
            } else {
                if (flowerbed[i - 1] == 0 && flowerbed[i + 1] == 0) { //数组中间的位置,需要判断之前和之后的是否有花。
                    n--;
                    flowerbed[i] = 1;
                }
            }

        }
        return n <= 0;
    }

复杂度

一趟遍历,时间复杂度是O(n),空间复杂度为O(1)

其他

该方法会修改数组。