Problem Overview
LeetCode 605 — Can Place Flowers gives you a flowerbed array of 0s and 1s, where 1 means a flower is already planted and 0 means the plot is empty. You are also given an integer n representing the number of new flowers you want to plant. You must return true if you can plant all n flowers without placing any two flowers in adjacent plots.
The adjacency constraint means that if you plant at position i, both position i-1 and position i+1 must remain empty. The original flowers already in the bed must also be respected — you cannot plant next to an existing 1.
This problem is a classic easy-level greedy puzzle that tests whether you can reason about local decisions and their global impact. It appears frequently in introductory algorithm courses and as a warm-up in real interviews.
- Input: integer array flowerbed of 0s and 1s, and integer n
- A flower at position i blocks planting at i-1 and i+1
- Return true if n flowers can be planted without adjacency violations
- Return false otherwise — even if you can plant some but not all
- Constraints: 1 <= flowerbed.length <= 20,000; flowerbed[i] is 0 or 1; no two existing flowers are adjacent; 0 <= n <= flowerbed.length
Greedy Placement
The greedy strategy is to scan the flowerbed from left to right and plant a flower at every valid position you encounter. A position i is valid if three conditions hold: flowerbed[i] is 0, the left neighbor (flowerbed[i-1]) is 0 or i equals 0, and the right neighbor (flowerbed[i+1]) is 0 or i equals the last index.
When you find a valid position, plant immediately: set flowerbed[i] = 1 and increment your count. Then continue scanning. If your count reaches n at any point, return true early. After the full scan, return count >= n.
The reason greedy works here is subtle but important. Planting as early as possible never prevents a future flower from being placed. If you skip a valid position and plant later instead, you can only do equal or worse — you gain nothing by waiting. The earliest valid spot is both locally and globally optimal.
Why Greedy Works
Planting at the earliest valid spot never blocks more flowers than skipping it. Each placement is locally optimal (satisfies all constraints) and globally optimal (does not reduce the maximum count achievable). This is the key insight that makes the greedy approach provably correct.
Algorithm Steps
The algorithm is a single linear pass with a counter. Initialize count = 0 and iterate over every index i from 0 to len(flowerbed) - 1. At each index, evaluate the three conditions in sequence. If all three pass, plant and increment. Return early as soon as count reaches n.
After the loop, return whether count >= n. This handles the edge case where n is 0 — you never need to plant anything, so the answer is immediately true (the loop never runs, count stays 0, and 0 >= 0 is true).
This approach modifies the flowerbed array in-place, which is allowed by the problem. If you need to preserve the original input, make a copy first. The in-place modification is what makes the adjacency check correct for the next position.
- 1Initialize count = 0
- 2For each index i from 0 to len(flowerbed) - 1:
- 3 Check condition 1: flowerbed[i] == 0
- 4 Check condition 2: i == 0 or flowerbed[i-1] == 0
- 5 Check condition 3: i == len-1 or flowerbed[i+1] == 0
- 6 If all three true: set flowerbed[i] = 1, count++
- 7 If count >= n: return true immediately
- 8After loop: return count >= n
Boundary Handling
The first and last positions need special treatment because they have only one neighbor instead of two. Position 0 has no left neighbor, so treat the imaginary left neighbor as 0 — meaning it is always empty. Position len-1 has no right neighbor, so treat the imaginary right neighbor as 0 as well.
In code, this translates to two short-circuit conditions. For the left neighbor: (i == 0 or flowerbed[i-1] == 0). For the right neighbor: (i == len-1 or flowerbed[i+1] == 0). These expressions evaluate to true at boundaries without any index-out-of-bounds errors.
This boundary logic is the most common source of bugs in solutions to this problem. Missing a boundary check leads to index errors or incorrect results at the edges of the array. Always verify your solution with a single-element flowerbed like [0] with n=1.
Padding Alternative
An alternative approach pads the array with a 0 on both ends: padded = [0] + flowerbed + [0]. Then iterate from index 1 to len-1 of the padded array and always check padded[i-1] and padded[i+1] without boundary conditions. Cleaner code, but uses O(n) extra space.
Walk-Through Example
Consider flowerbed = [1, 0, 0, 0, 1] with n = 1. We scan left to right. Position 0: flowerbed[0] = 1, skip. Position 1: flowerbed[1] = 0, left neighbor = flowerbed[0] = 1 (not 0), skip. Position 2: flowerbed[2] = 0, left = flowerbed[1] = 0, right = flowerbed[3] = 0 — all conditions pass! Plant here: set flowerbed[2] = 1, count = 1. Since count >= n (1 >= 1), return true immediately.
Now try flowerbed = [1, 0, 0, 0, 1] with n = 2. Position 2 plants as above, count = 1. Position 3: left = flowerbed[2] = 1 (just planted), skip. Position 4: flowerbed[4] = 1, skip. End of array, count = 1 < 2, return false.
Try flowerbed = [0, 0, 1, 0, 0] with n = 1. Position 0: current = 0, no left (treat as 0), right = flowerbed[1] = 0 — plant! count = 1 >= 1, return true. This shows how left boundary handling allows position 0 to be planted when the next cell is empty.
- 1flowerbed = [1,0,0,0,1], n=1
- 2i=0: flowerbed[0]=1 → skip
- 3i=1: flowerbed[1]=0, left=flowerbed[0]=1 → skip (left neighbor is 1)
- 4i=2: flowerbed[2]=0, left=flowerbed[1]=0, right=flowerbed[3]=0 → PLANT! count=1
- 5count=1 >= n=1 → return true
Code Walkthrough: Python and Java
In Python: def canPlaceFlowers(flowerbed, n): for i in range(len(flowerbed)): if flowerbed[i]==0 and (i==0 or flowerbed[i-1]==0) and (i==len(flowerbed)-1 or flowerbed[i+1]==0): flowerbed[i]=1; n-=1; if n<=0: return True; return n<=0. Time complexity: O(n) — single pass. Space complexity: O(1) — no extra data structures, modifies input in-place.
In Java: public boolean canPlaceFlowers(int[] flowerbed, int n) { for (int i = 0; i < flowerbed.length; i++) { if (flowerbed[i]==0 && (i==0 || flowerbed[i-1]==0) && (i==flowerbed.length-1 || flowerbed[i+1]==0)) { flowerbed[i]=1; n--; if (n<=0) return true; } } return n<=0; }. The early return keeps the loop short-circuit when enough flowers are placed.
Both implementations decrement n directly instead of maintaining a separate counter — this simplifies the final check to n <= 0. The pattern is identical across languages: single for loop, three conditions, in-place update, early exit.
Must Update In-Place
You MUST set flowerbed[i] = 1 after planting — do not just decrement n. Without updating the array, the next position sees 0 as its left neighbor and may incorrectly plant adjacent to the flower you just counted. This produces wrong answers for cases like [0,0,0,0,0] with n=3.