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:
  - slug: greedy
    is_optimal: true

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

    &nbsp;

    **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`

    &nbsp;

    **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

    &nbsp;

    **Step 4: Return the result**

    - After the loop, return `count >= n`

    &nbsp;

    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.
