假设有一个很长的花坛,一部分地块种植了花,另一部分没有钟。花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给出一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false。
package com.loo;
public class CanPlaceFlowers {
public static void main(String[] args) {
int[] arr = new int[] {1 , 0 , 0 , 0 , 1};
int n = 2;
System.out.println(canPlaceFlowers3(arr , n));
}
public static boolean canPlaceFlowers1(int[] flowers , int n) {
if (flowers == null || flowers.length == 0 || n < 0) {
return false;
}
int len = flowers.length;
int prev = -1;
int count = 0;
for (int i=0;i<len;i++) {
if (flowers[i]==1) {
if (prev < 0) {
// 第一次遇到有种花的地方,假设从左到右,因左边 i 已经在flowers中为1 ,所以,i-1 坐标不能种花,i - 2 才能种,但需满足 i-2>=0(flowers坐标需>=0),故在数组 flowers 的 i 坐标左边还能种 i/2朵花.
count += i/2;
} else {
// 第 i 个坐标和上一次 prev 个坐标已经种有花,那么从 prev 到 i 之间能种多少花呢?从 prev 到 i 之间共有 i - prev 个空的地方,
// 但考虑到相邻的地块上不能种,在 prev+1 和 i-1 这两个地方不能种,故从 prev 到 i 之间共有 i - prev - 2 个空的地方,相邻不能种花,所以能种花的地方有 (i - prev - 2)/2
count += (i - prev - 2)/2;
}
if (count >= n) { // 如果能种花的地方已经满足直接返回
return true;
}
// 保存本次种有花的坐标
prev = i;
}
}
if (prev < 0) { // flowers 没有种花,是块空的地方
count += (len + 1) / 2;
} else {
// flowers 种有花,最右边种的那个坐标是 prev ,相邻不能种花,所以 prev + 1 这个地方不能种,故剩下右边可以种花的地方是 (len - prev - 1)/2
count += (len - prev - 1)/2;
}
return count >= n;
}
public static boolean canPlaceFlowers2(int[] flowers , int n) {
if (flowers == null || flowers.length == 0 || n < 0) {
return false;
}
for (int i=0;i<flowers.length;i++) {
if (n <= 0) { // 如果能种花的地方已经满足直接返回,即花种完了
return true;
}
if (flowers[i] == 1) { // 种有花
continue;
}
if (i>0 && flowers[i-1]==1) { // 相邻不能种花,如果左边已经种有,则忽略
continue;
}
if (i<flowers.length-1 && flowers[i+1]==1) { // 相邻不能种花,如果右边已经种有,则忽略
continue;
}
flowers[i] = 1; // 种花
n--; // 要求种的花数量减一
}
return n<=0;
}
public static boolean canPlaceFlowers3(int[] flowers , int n) {
if (flowers == null || flowers.length == 0 || n < 0) {
return false;
}
int len = flowers.length;
for (int i=0;i<len;) {
if (flowers[i] == 1) { // 相邻不能种花,故下一个位置忽略,直接跳到下一个的下一个位置
i += 2;
} else if (i == len - 1 || flowers[i+1] == 0) { // 如果是最后一个位置,或者是 i 的下一个位置没种有花,则可以种花
n--; // 种上花,次数减一
if (n <= 0) { // 如果能种花的地方已经满足直接返回,即花种完了
return true;
}
i += 2; // 如果花还没有种完,则本次种完之后考虑下一个位置的下一个位置
} else { // 这里说明是 flowers[i+1]=1,那么考虑 i 的下一个位置的下一个位置的下一个位置,即 i+3 的位置
i += 3;
}
}
return n <= 0;
}
}