Skip to article
ALGORITHMICSDSA / Greedy
DSAeasy5 min read

Can Place Flowers

Plant as early as possible — and the function that quietly rewrites its caller's garden.


A row of plots, some already planted. No two flowers may be adjacent. Can you plant n more?

canPlaceFlowers([]int{1, 0, 0, 0, 1}, 1) // true
canPlaceFlowers([]int{1, 0, 0, 0, 1}, 2) // false

Plant at the first opportunity

Walk left to right. A plot is plantable when it is empty and both neighbours are empty — with the ends counting as empty, since there is nothing beyond them.

1 / 5

plant 1 · 1 still to place

···
left clear: true right clear: true

Already occupied. Nothing to decide.

func canPlaceFlowers(flowerbed []int, n int) bool {
if n == 0 {
return true
}
for i, v := range flowerbed {
left := i == 0 || flowerbed[i-1] == 0
right := i == len(flowerbed)-1 || flowerbed[i+1] == 0
if left && right && v == 0 {
n--
flowerbed[i] = 1
}
if n == 0 {
return true
}
}
return false
}

O(n)O(n) time, one pass.

It rewrites the caller’s flowerbed

Counting instead of simulating

There is a closed form. A run of k consecutive empty plots between two flowers holds (k1)/2\lfloor (k-1)/2 \rfloor new ones; a run at either end holds k/2\lfloor k/2 \rfloor, because it only has a neighbour on one side.

Summing those and comparing to n is the same O(n)O(n) and it never writes to the input. It is also easier to get wrong — three cases instead of one — which is why the simulation is the version to reach for first and this is the version to reach for when the input is not yours to modify.