种花问题
题目(leetcode605)
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 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
代码
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int l = flowerbed.length;
int [] dp = new int [l+1];
if(flowerbed.length ==1){
if(flowerbed[0]==0){
return 1>=n;
}
else{
return 0>=n;
}
}
else{
dp[0] = 0;
if(flowerbed[0]==0&flowerbed[1]==0){
dp[1]=1;
flowerbed[0]=1;
}
else{
dp[1]=0;
}
for(int i=2;i<=l;i++){
if(flowerbed[i-1]==0&flowerbed[i-2]==0){
dp[i] = Math.max(dp[i-1],dp[i-2]+1);
flowerbed[i-1]=1;
}
else if(flowerbed[i-1]==1&flowerbed[i-2]==1){
dp[i] =dp[i-1]-1;
}
else{
dp[i] =dp[i-1];
}
}
return dp[l]>=n;
}
}
官方题解用贪心做的,由于正在学动态规划,我用动态规划解答了。
明确动态规划三要素:最优子结构、边界和状态转移函数。
最优子结构
假设地的数量为i,i块地能种的最多的花的数量为dp[i],那么显然i块地最多能种的花的数量为max(dp[i]-1,dp[i-2]+1),即为最优子结构。
边界
没有地,种花数为0
1块地与2块地(flowerbed.length ==1或2),种花数根据原本有无种树判断。
状态转移函数
根据最优子结构得到
因为要根据原来的地有无种树判断,因此,执行最优子结构的前提为当前地无种树,并且前一块地也无种树,满足这一条件,即在此地种树,即
if(flowerbed[i-1]==0&flowerbed[i-2]==0){
dp[i] = Math.max(dp[i-1],dp[i-2]+1);
flowerbed[i-1]=1;
但这样递推种树容易导致,下一块地有种树的情况下,当前地也种树,因此,需要在递推时判断,如果当前地有种树,前一块地也有种树,那么这种情况下种树数量要-1,因为题目中提示flowerbed 中不存在相邻的两朵花,连续两块地都有树仅由递推时种树导致,即
else if(flowerbed[i-1]==1&flowerbed[i-2]==1){
dp[i] =dp[i-1]-1;
除此之外的01或者10情况都不能种树,那么最多种花数量等于少一块地的种花数,即
else{
dp[i] =dp[i-1];
}
最终输出返回 l l l 块地最大种花数 d p [ l ] dp[l] dp[l] 是否大于 n n n即可。