种花问题
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组
flowerbed
表示花坛,由若干0
和1
组成,其中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]
为0
或1
flowerbed
中不存在相邻的两朵花0 <= n <= flowerbed.length
跳格子解法
题目要求是否能在不打破规则的情况下插入n朵花,与直接计算不同,采用“跳格子”的解法只需遍历不到一遍数组,处理以下两种不同的情况即可:
【1】当遍历到index遇到1时,说明这个位置有花,那必然从index+2的位置才有可能种花,因此当碰到1时直接跳过下一格。 【2】当遍历到index遇到0时,由于每次碰到1都是跳两格,因此前一格必定是0,此时只需要判断下一格是不是1即可得出index这一格能不能种花,如果能种则令n减一,然后这个位置就按照遇到1时处理,即跳两格;如果index的后一格是1,说明这个位置不能种花且之后两格也不可能种花(参照【1】),直接跳过3格。
当n减为0时,说明可以种入n朵花,则可以直接退出遍历返回true;如果遍历结束n没有减到0,说明最多种入的花的数量小于n,则返回false。
时间复杂度:O(n)
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
i, length = 0, len(flowerbed)
while i < length and n > 0:#遍历到最后一个元素和n减到0结束循环
if flowerbed[i] == 1:
i += 2#跳两格才可能可以种花
elif flowerbed[i] == 0:
if i + 1 == length:#如果是最后一个元素
n -= 1#种一朵
i += 1
elif flowerbed[i+1] == 0:#如果后一格没种花
n -= 1#种一朵
i += 2
elif flowerbed[i+1] == 1:#后一个已经种了花
i += 3#跳三格才可能可以种花
return n == 0#如果n减到0则空位够种花,反之不够种
举例解释:
优化后(时间复杂度不变但更具Python风格)
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
length = len(flowerbed)
flowerbed = [0] + flowerbed + [0] # 对边缘进行填充以减少边缘情况
for i in range(1, length + 1): # 从索引 1 开始,直到 length + 1,因为有填充
if flowerbed[i-1:i+2] == [0, 0, 0]: # 检查前一个、当前和下一个位置是否可以种植花
flowerbed[i] = 1 # 种植一朵花
n -= 1 # 减少数量
return n <= 0