title: Can Place Flowers slug: can-place-flowers difficulty: easy leetcode_id: 605 leetcode_url: https://leetcode.com/problems/can-place-flowers/ categories: - arrays patterns: - greedy function_signature: "def can_place_flowers(flowerbed: list[int], n: int) -> bool:" test_cases: visible: - input: { flowerbed: [1, 0, 0, 0, 1], n: 1 } expected: true - input: { flowerbed: [1, 0, 0, 0, 1], n: 2 } expected: false hidden: - input: { flowerbed: [0], n: 1 } expected: true - input: { flowerbed: [1], n: 0 } expected: true - input: { flowerbed: [0, 0, 0, 0, 0], n: 3 } expected: true - input: { flowerbed: [0, 0, 0, 0, 0], n: 4 } expected: false - input: { flowerbed: [1, 0, 0, 0, 0, 1], n: 1 } expected: true - input: { flowerbed: [0, 0, 1, 0, 0], n: 2 } expected: true - input: { flowerbed: [1, 0, 1, 0, 1], n: 1 } expected: false description: | You have a long flowerbed in which some of the plots are planted, and some are not. However, flowers cannot be planted in **adjacent** plots. Given an integer array `flowerbed` containing `0`'s and `1`'s, where `0` means empty and `1` means not empty, and an integer `n`, return `true` *if* `n` *new flowers can be planted in the flowerbed without violating the no-adjacent-flowers rule and* `false` *otherwise*. constraints: | - `1 <= flowerbed.length <= 2 * 10^4` - `flowerbed[i]` is `0` or `1` - There are no two adjacent flowers in `flowerbed` - `0 <= n <= flowerbed.length` examples: - input: "flowerbed = [1,0,0,0,1], n = 1" output: "true" explanation: "We can plant one flower at index 2. The flowerbed becomes [1,0,1,0,1], which satisfies the no-adjacent-flowers rule." - input: "flowerbed = [1,0,0,0,1], n = 2" output: "false" explanation: "There is only one valid spot (index 2) to plant a flower. We cannot plant 2 flowers without violating the adjacency rule." explanation: intuition: | Imagine walking through a garden path where each plot is either empty (`0`) or has a flower (`1`). Your task is to plant as many flowers as possible without placing two flowers next to each other. The key insight is that we can make a **greedy decision** at each empty plot: if we *can* plant a flower here (no adjacent flowers), we *should* plant it immediately. There's never a benefit to "saving" a spot for later — planting now can only help us, never hurt us. Think of it like this: you're walking left to right. At each empty plot, you check three things: - Is the plot to my left empty (or am I at the start)? - Is the current plot empty? - Is the plot to my right empty (or am I at the end)? If all three conditions are true, plant a flower and move on. By greedily planting whenever possible, you guarantee the maximum number of flowers. approach: | We solve this using a **Single Pass Greedy Approach**: **Step 1: Initialise a counter** - `count`: Set to `0` to track how many flowers we've planted   **Step 2: Iterate through the flowerbed** - For each position `i`, check if we can plant a flower: - Current plot must be empty: `flowerbed[i] == 0` - Left neighbour must be empty or out of bounds: `i == 0` or `flowerbed[i-1] == 0` - Right neighbour must be empty or out of bounds: `i == len(flowerbed) - 1` or `flowerbed[i+1] == 0` - If all conditions are met, plant the flower: - Set `flowerbed[i] = 1` (this prevents planting at `i+1`) - Increment `count`   **Step 3: Early termination (optimisation)** - If `count >= n` at any point, we can return `True` immediately - No need to continue checking once we've planted enough flowers   **Step 4: Return the result** - After the loop, return `count >= n`   This greedy approach works because planting a flower at the earliest valid position never prevents us from achieving the maximum count — it only restricts the immediately adjacent plot, which wouldn't have been valid anyway. common_pitfalls: - title: Forgetting Boundary Conditions description: | The first and last plots only have one neighbour to check, not two. For position `0`, there is no left neighbour — treat it as empty. Similarly, for the last position, there is no right neighbour. Failing to handle boundaries leads to index-out-of-bounds errors or incorrect results for flowerbeds like `[0,0,1]` where the first plot is plantable. wrong_approach: "Always checking both neighbours without boundary checks" correct_approach: "Use `i == 0` or `i == len-1` to handle edge positions" - title: Not Marking Planted Flowers description: | After deciding to plant at position `i`, you must update `flowerbed[i] = 1`. If you only increment a counter without modifying the array, the next iteration will incorrectly think position `i+1` has an empty left neighbour. This leads to planting adjacent flowers. Example: In `[0,0,0]`, if you plant at index `0` but don't mark it, you'll also "plant" at index `1`, violating the adjacency rule. wrong_approach: "Only counting without modifying the array" correct_approach: "Set flowerbed[i] = 1 after planting" - title: Checking n > 0 Instead of count >= n description: | When `n = 0`, the answer should always be `True` — you don't need to plant any flowers. Some implementations decrement `n` each time they plant, then check `n <= 0`. This works, but be careful with the initial check: if `n == 0` from the start, return `True` immediately or ensure your loop handles it correctly. key_takeaways: - "**Greedy validity**: When a locally optimal choice (plant now) never hurts the global solution, greedy works" - "**In-place modification**: Updating the input array lets us track state without extra space" - "**Boundary handling**: Always consider edge cases at array boundaries — they often have special rules" - "**Early termination**: Once you've achieved the goal (`count >= n`), stop early for efficiency" time_complexity: "O(n). We traverse the flowerbed array once, where `n` is the length of the array." space_complexity: "O(1). We modify the input array in-place and use only a constant amount of extra space for the counter." solutions: - approach_name: Single Pass Greedy is_optimal: true code: | def can_place_flowers(flowerbed: list[int], n: int) -> bool: count = 0 length = len(flowerbed) for i in range(length): # Check if current plot is empty if flowerbed[i] == 0: # Check left neighbour (or start of array) left_empty = (i == 0) or (flowerbed[i - 1] == 0) # Check right neighbour (or end of array) right_empty = (i == length - 1) or (flowerbed[i + 1] == 0) # If both neighbours are empty, plant here if left_empty and right_empty: flowerbed[i] = 1 # Mark as planted count += 1 # Early exit if we've planted enough if count >= n: return True return count >= n explanation: | **Time Complexity:** O(n) — Single pass through the flowerbed. **Space Complexity:** O(1) — We modify the input array in-place and use only a counter variable. We iterate through each plot once. When we find a valid spot (current empty, left empty or boundary, right empty or boundary), we plant and mark it. The modification prevents consecutive plantings. Early termination provides a small optimisation when `n` is small. - approach_name: Count Consecutive Zeros is_optimal: false code: | def can_place_flowers(flowerbed: list[int], n: int) -> bool: # Pad with zeros for easier boundary handling padded = [0] + flowerbed + [0] count = 0 zeros = 0 for plot in padded: if plot == 0: zeros += 1 else: # Calculate flowers that fit in this gap # For k consecutive zeros, we can fit (k-1)//2 flowers count += (zeros - 1) // 2 zeros = 0 # Don't forget the trailing zeros count += (zeros - 1) // 2 return count >= n explanation: | **Time Complexity:** O(n) — Single pass through the padded array. **Space Complexity:** O(n) — We create a new padded array. This approach counts consecutive zeros between flowers. For `k` consecutive empty plots (including virtual padding), we can plant `(k-1) // 2` flowers. The padding simplifies boundary handling. While correct, this uses extra space compared to the in-place greedy approach.