刚开始尝试写这个东西,希望大家看了这篇文章后能够指出不足之处,谢谢!!
1.问题描述:(想必大家已经对题目烂熟于心了哈!但是出于习惯我复制粘贴上了)
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false。
2.代码:(我相信有些人思路什么的都有,只是想看代码,所以把代码放前面了)
class Solution {
public:
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
//两种特殊情况
if(n == 0){
return true;
}
//当n > flowerbed.size()/2 + 1时,一定是false。
if(n > flowerbed.size() / 2 + 1){
return false;
}
//在数组的两端添加0,免去分类讨论的麻烦。
flowerbed.emplace(flowerbed.begin(), 0);
int count = 0; //能够种植的数量
int num = 1; // 计数 每当num == 3时,++count;
//每三个相邻的0可以种一朵花,注:下一次num计数是从这次的第三个0开始的!!!
for(int i = 1; i < flowerbed.size(); ++i){
if(flowerbed[i] != 0){
num = 0;
}else{
++num;
if(num == 3){
++count;
num = 1;
}
}
}
//数组最后是00就可以种一盆了。
if(num == 2){
++count;
}
return {count >= n? true:false};
}
};
3.解题思路:
既然花不能种在相邻的地块上,那么每有三个相邻的空地则可以种植一盆花,把问题转化为遍历数组中三个相邻的0,每有一组则可以种植一盆,以num为相邻的0的数目,count为可以种植的花的盆数。当flowerbed[i]==0,++num,当num == 3时,++count,把num重置为1;当flowerbed[i]== 1,num清零。
4.细节处理:
@.当数组的第一个值是1或者是0似乎需要分类讨论才能准确的确定count的值,为了避免这种麻烦,我采取在数组的头部添加一个0,这样就不需要分类讨论了。
@.每当num == 3(出现了连续的三个0)时,count的值加一,这时num的值是不归零的,而是要设置为1(这是我认为最重要的点),因为第三个0可以参与到后面的0的计数中,比如数组是010000010,种最多的花后变成010101010,也就是5个连续的0可以种2盆,而不需要6个0。(这里表达的似乎不太好,如果我想到了更好的再回来改。)
@.有两种情况是可以直接判断出结果的:第一种是n == 0,一定是true;第二种是n>(flowerbed.size()/2 + 1),即n值已经大于理论上数组能够容纳的 1 的数量,一定是false。
5.代码部分
@.通过emplace()函数或者insert()函数均可以实现添加元素的功能。emplace()每次只能在某个位置添加一个元素,速度较快;insert()函数可以在某个位置添加一个或者多个元素或者是添加一个数组,速度较慢。所以我在程序中选择了emplace()函数。
@.其实在数组的尾部也添加一个0就不需要最后的判断count == 2 了,但是速度上慢了许多,所以折中了一下。