题目:
示例:
分析:
给一个数组表示一个花园,其中0表示空地,1表示已经有花种下去了.
空地可以种花,但是花和花之间不能相邻,即数组中不能有两个连续的1.
给一个数n,问我们能不能在花园里种n朵花.
我们可以找出我们所能种的最多的数量(而不是只种n朵),然后比较我们最多能种的数量是否大于等于n.所以我们可以遍历整个数组,找出可以种花的地方,然后置1表示把花种下去了(也为了影响判断后续土地能否种花).
为了保证我们种的花是数量最多的,我们需要让首尾两侧在能种花的情况下都种上,为什么需要先种首尾两侧呢?
因为在其他地方种花需要判断左右两侧是否都为0(空地),而在首部只需要考虑右侧,在尾部只需要考虑左侧.并且由于我们要种最多的花,因此我们需要把花种的紧凑一些,所以在首尾处留0(空地)不太符合我们的要求对吧.
可以来举个例子,以首部为例,若是首部的连续空地数为奇数,则会如下例:
我们可以看出结果1(首部种花)和结果2(首部不种花)的结果是一样的.
若是首部的连续空地数为偶数,则会如下例:
可以看出首部种花的结果会比首部不种花的结果多,反过来尾部也是一样的.
因此我们可以先把首尾两处单独拎出来判断(数组长度为1时也要单独判断):
int res=0;
int len=flowerbed.size();
if(len==1){ //数组长度为1时的判断
if(flowerbed[0]==0) res++;
return res>=n;
}
if(flowerbed[0]==0 && flowerbed[1]==0){ //若是首部前两个都为0,则在首部种一朵花
flowerbed[0]=1;
res++;
}
if(flowerbed[len-1]==0 && flowerbed[len-2]==0){ //若是尾部后两个都为0,则在尾部中一朵花
flowerbed[len-1]=1;
res++;
}
然后我们可以写一个函数来判断其余土地能不能种花:
bool check(int index,vector<int>& flowerbed){
//如果相邻的土地都是空的,则可以种花
if(flowerbed[index-1]==0 && flowerbed[index+1]==0){
flowerbed[index]=1;
return true;
}
return false;
}
然后循环遍历,若是遇到空地,则用函数判断能否种地,完整代码如下:
class Solution {
public:
//检查是否能种花
bool check(int index,vector<int>& flowerbed){
if(flowerbed[index-1]==0 && flowerbed[index+1]==0){
flowerbed[index]=1;
return true;
}
return false;
}
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
int res=0;
int len=flowerbed.size();
//特殊情况特殊处理
if(len==1){
if(flowerbed[0]==0) res++;
return res>=n;
}
//初始化首部土地
if(flowerbed[0]==0 && flowerbed[1]==0){
flowerbed[0]=1;
res++;
}
//初始化尾部土地
if(flowerbed[len-1]==0 && flowerbed[len-2]==0){
flowerbed[len-1]=1;
res++;
}
for(int i=1;i<len-1;i++){
if(flowerbed[i]==0 && check(i,flowerbed)) res++;
}
return res>=n;
}
};