
本文详解 leetcode 605 题“种花问题”的高效解法:通过单次遍历、原地判断相邻约束,避免冗余数组与重复扫描,在 o(n) 时间、o(1) 空间内准确判断能否种植 n 朵花。
本文详解 leetcode 605 题“种花问题”的高效解法:通过单次遍历、原地判断相邻约束,避免冗余数组与重复扫描,在 o(n) 时间、o(1) 空间内准确判断能否种植 n 朵花。
原始代码尝试用 empty[] 数组预存所有空位索引,再对每个空位反复检查左右邻居——这不仅引入了额外空间开销(O(n)),还导致逻辑混乱:内层循环中修改 flowerbed 后未同步更新 empty,且边界处理错误(如 v = empty[h] - 1 >= 0 ? ... : 0 将越界左邻强制设为索引 0,造成误判);更严重的是,外层 j 循环仅执行 n 次,却未保证每次都能成功种花,也未在提前满足条件时及时退出。
正确的思路是贪心 + 一次线性扫描:从左到右遍历花床,对每个位置 i,仅当其自身及左右邻居(若存在)均为 0 时,才在此处种花(置 flowerbed[i] = 1),并计数 count++。一旦 count >= n,立即返回 true。
关键在于统一处理边界:对于位置 i,只需验证:
- flowerbed[i] == 0
- 左侧安全:i == 0 || flowerbed[i-1] == 0
- 右侧安全:i == flowerbed.length-1 || flowerbed[i+1] == 0
三者同时成立,即可种花。该条件自然涵盖首尾位置(如 i==0 时跳过左检,i==len-1 时跳过右检),无需特殊分支。
以下是优化后的参考实现:
public class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
if (n == 0) return true;
int count = 0;
for (int i = 0; i = n) {
return true;
}
}
}
return false;
}
}
注意事项:
- 勿修改输入前提:若题目要求不可修改原数组,可将 flowerbed[i] = 1 替换为逻辑标记(如跳过后续相邻位),但本题允许修改,故直接赋值最简洁;
- 提前终止:每次成功种花后立即检查 count >= n,避免无谓遍历;
- 边界安全:使用短路逻辑 || 和 &&,确保 i-1 或 i+1 不越界访问;
- 时间/空间复杂度:严格 O(n) 时间、O(1) 额外空间,优于原方案的 O(n) 空间与潜在 O(n²) 行为。
此方法直击问题本质——在满足不相邻约束下最大化可种植数,是贪心策略的经典应用。掌握这种边界统一化判断技巧,对解决类似“间隔放置”类问题(如安排会议室、分配资源)极具迁移价值。










