题目
解答
方案一
public class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
if (flowerbed == null || flowerbed.length == 0) {
return false;
}
if (flowerbed.length < 2) {
return (flowerbed[0] == 1 ? 0 : 1) >= n;
}
if (flowerbed.length < 3) {
int count = 0;
if (flowerbed[0] == 0 && flowerbed[1] == 0) {
count = 1;
}
return count >= n;
}
int length = flowerbed.length;
int[] counts = new int[length];
if (flowerbed[0] == 0 && flowerbed[1] == 0) {
counts[0] = 1;
}
if (flowerbed[0] == 1) {
counts[1] = 0;
} else {
// flowerbed[0] == 0
counts[1] = flowerbed[1] == 1 ? 0 : 1;
}
int max = length - 1;
for (int i = 2; i < max; ++i) {
if (flowerbed[i - 1] == 1 || flowerbed[i] == 1 || flowerbed[i + 1] == 1) {
counts[i] = counts[i - 1];
} else {
counts[i] = Math.max(counts[i - 2] + 1, counts[i - 1]);
}
if (counts[i] >= n) {
return true;
}
}
if (flowerbed[max] == 1 || flowerbed[max - 1] == 1) {
counts[max] = counts[max - 1];
} else {
counts[max] = Math.max(counts[max - 2] + 1, counts[max - 1]);
}
return counts[max] >= n;
}
}
方案二
public class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int length = flowerbed.length;
int[] flowerbedNew = new int[length + 2];
System.arraycopy(flowerbed, 0, flowerbedNew, 1, length);
flowerbedNew[0] = 0;
flowerbedNew[length + 1] = 0;
for (int i = 1; i < length; ++i) {
if (flowerbedNew[i - 1] == 0 && flowerbedNew[i] == 0 && flowerbedNew[i + 1] == 0) {
--n;
flowerbedNew[i] = 1;
}
if (n <= 0) {
return true;
}
}
if (n <= 0) {
return true;
}
return false;
}
}
要点
直观的说,方案一的实现很丑陋。
依据题目的定义,有个简单的思路,即每三个位置可以种一株花,那么在输入数据的前、后增加哨兵元素,可以规避边界条件的处理,一定程度上简化实现。
本题目在贪心算法的分类下,后续补充基于贪心算法的求解实现。
准备的用例,如下
@Before
public void before() {
t = new Solution();
}
@Test
public void test01() {
assertTrue(t.canPlaceFlowers(new int[] { 1, 0, 0, 0, 1 }, 1));
}
@Test
public void test02() {
assertFalse(t.canPlaceFlowers(new int[] { 1, 0, 0, 0, 1 }, 2));
}
@Test
public void test03() {
assertFalse(t.canPlaceFlowers(new int[] { 1 }, 2));
}
@Test
public void test04() {
assertFalse(t.canPlaceFlowers(new int[] { 1 }, 1));
}
@Test
public void test05() {
assertTrue(t.canPlaceFlowers(new int[] { 1 }, 0));
}
@Test
public void test06() {
assertTrue(t.canPlaceFlowers(new int[] { 0 }, 0));
}
@Test
public void test07() {
assertFalse(t.canPlaceFlowers(new int[] { 1, 0 }, 2));
}
@Test
public void test08() {
assertFalse(t.canPlaceFlowers(new int[] { 1, 0 }, 1));
}
@Test
public void test09() {
assertTrue(t.canPlaceFlowers(new int[] { 0, 0 }, 1));
}
@Test
public void test10() {
assertFalse(t.canPlaceFlowers(new int[] { 0, 0 }, 2));
}
@Test
public void test11() {
assertFalse(t.canPlaceFlowers(new int[] { 1, 0, 0, 0, 0, 1 }, 2));
}
@Test
public void test12() {
assertTrue(t.canPlaceFlowers(new int[] { 0, 0, 1, 0, 1 }, 1));
}
@Test
public void test13() {
assertFalse(t.canPlaceFlowers(new int[] { 0, 1, 0 }, 1));
}
@Test
public void test14() {
assertFalse(t.canPlaceFlowers(new int[] { 1, 0, 1, 0, 0, 1, 0 }, 1));
}