Array Questions Part 3
======================
56. (LC 1) Two Sum
--------------------
`1. Two Sum `_
Easy
**Python3**
::
# My V (LC accepted 99, 50)
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hash_t = {}
for i, n in enumerate(nums):
pair = target - n
if pair in hash_t:
return [hash_t[pair], i]
hash_t[n] = i
**C++** [:ref:`14 `]
| nums={3,2,10,11,7,15}, target = 9
| **The naive approach**
| Iterate nums, for each number iterate the rest of nums and look for the pair_value=target-num.
| E.g. 3, 9-3=6, look for 6 to the right of 3.
| 2, 9-2=7, look for 7 to the right of 2.
.. code-block:: cpp
class Solution {
public:
vector twoSum(vector& nums, int target) {
vector result; //for two answer indices
for (auto it1 = nums.begin(); it1 != nums.end(); ++it1){
auto it2 = find(it1+1, nums.end(), target - *it1); //it1+1 to look to the right of cur num only
if (it2 != nums.end()){ //found the number
result.push_back(it1 - nums.begin()); //iterators subtraction allows to obtain a proper number of an index, not iterator
result.push_back(it2 - nums.begin());
break; //cannot use return here, otherwise error: non-void function does not return a value in all control paths
}
}
return {}; //returning empty vector if complement was not found
}
};
| **Approach 2**
| Using hash map.
| keys: nums values, values: their position
| Insert all elems into the map. (The catch is not to insert all values, then traverse
| again and search, but do it simultaneously.)
.. code-block:: cpp
class Solution {
public:
vector twoSum(vector& nums, int target) {
unordered_map _map;
for (int i = 0; i < nums.size(); ++i){
int num = nums[i];
int complement = target - num;
auto it = _map.find(complement); //returns iter if finds key in map, end of container iter otherwise. Iter points to key, value pair.
if(it != _map.end()){ //found
return {it->second, i}; //iter points at the (key,value) pair, *iter is tha pair. (*iter).mem, we want the second, i.e. value. i is the index of cur num
}
_map[num] = i; //insert into hash map, like in Python
}
return {}; //returning empty vector if complement was not found
}
};
| Note how we iterate:
| Approach 1 -> vector -> iterators
| Approach 1 -> unordered_map -> subscripting
### My V (Approach 2 but with iterators. LC accepted 80, 30)
.. code-block:: cpp
class Solution {
public:
vector twoSum(vector& nums, int target) {
unordered_map _map;
vector result;
for (auto it1 = nums.begin(); it1 != nums.end(); ++it1){
int complement = target - *it1;
auto it2 = _map.find(complement);
if (it2 != _map.end()){
result.push_back(it2->second);
result.push_back(it1 - nums.begin());
break;
}
_map[*it1] = it1 - nums.begin();
}
return result;
}
};
57. (LC 15) 3Sum
-------------------
`15. 3Sum `_
*(Medium)*
| **Solution 0**
| My V (Time Limit Exceeded on case 308/313, so almost works)
| (Brute force, use Python std lib.)
::
from itertools import combinations
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# Out of all combinations with size 3, choose those that sum to 0.
combos = [c for c in combinations(nums, 3) if sum(c) == 0]
# Choose only unique combinations
res = set([tuple(sorted(l)) for l in combos])
res = list([list(item) for item in res])
return res
| Key notes:
| -Pictorially:
::
# [-4,-1,-1,0,1,2]
# a L R
| -sort input
| -a is current number, use i,a enumerate(nums), calculate L,R from i.
| -2 edge cases: if a is positive, if a==nums[i-1]
| -nested while l List[List[int]]:
nums.sort()
n = len(nums) - 1
res = []
for i, a in enumerate(nums[:n-1]):
if a > 0:
break
if i > 0 and a == nums[i-1]:
continue
L, R = i+1, n
while L < R:
if a + nums[L] + nums[R] == 0:
res.append([a,nums[L],nums[R]])
while(L < R and nums[R] == nums[R-1]): R-=1
while(L < R and nums[L] == nums[L+1]): L+=1
R-=1
L+=1
elif a+nums[L]+nums[R] > 0: R-=1
else: L+=1
return res
**Solution 1** [:ref:`10 `] ::
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
nums.sort()
for i, a in enumerate(nums):
# Skip positive integers
if a > 0: #0
break
if i > 0 and a == nums[i - 1]: #1
continue
l, r = i + 1, len(nums) - 1 #2
while l < r:
threeSum = a + nums[l] + nums[r]
if threeSum > 0:
r -= 1
elif threeSum < 0:
l += 1
else:
res.append([a, nums[l], nums[r]])
l += 1
r -= 1
while nums[l] == nums[l - 1] and l < r: #3
l += 1
return res
#0 If current number (a) is positive, then all the following nums are positive
as well (sorted array), and we won't sum them to 0.
| #1 To avoid duplicates
| if it is the same number as prev, e.g. [-2,-2,0,3..], we don't use it.
| I.e. we don't use it as the again for triplets like [-2,0,2], [-2,0,2].
| (We can use it as a second like [-2,-2,4].)
#2 3 nums = Our current value and two pointers::
# [-4,-1,-1,0,1,2]
# a L R
| #3 To avoid duplicates
| Again if we have
::
# [-1,-1,-1,0,3..]
# a L
If we move L+=1, it will move to the same value, so we move L till it is a different value, or L meets R.
**Solution 1, V2** [:ref:`14 `] ::
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
if n < 3: return []
result = []
nums.sort()
for i in range(n-2):
if i == 0 or nums[i] != nums[i-1]:
j,k = i+1, n-1
while j < k:
sum = nums[i] + nums[j] + nums[k]
if sum == 0:
result.append([nums[i], nums[j], nums[k]])
while j < k and nums[j] == nums[j+1]: j += 1
while j < k and nums[k] == nums[k-1]: k -= 1
j, k = j+1, k-1
elif sum < 0: j += 1
else: k -= 1
return result
**C++**
My V (LC accepted 90, 60)
.. code-block:: cpp
class Solution {
public:
vector> threeSum(vector& nums) {
int n = nums.size();
vector> res;
sort(nums.begin(), nums.end());
for(int i=0; i != n-2; ++i){
if (nums[i] > 0)
break;
if (i > 0 && nums[i] == nums[i-1])
continue;
int L = i+1, R = n-1;
while(L < R){
if(nums[i] + nums[L] + nums[R] == 0){
res.push_back({nums[i], nums[L], nums[R]});
while(R > L && (nums[R] == nums[R-1])) --R;
while(R > L && (nums[L] == nums[L+1])) ++L;
--R;
++L;
}
else if(nums[i] + nums[L] + nums[R] > 0) --R;
else ++L;
}
}
return res;
}
};
Solution [:ref:`14 `]
.. code-block:: cpp
vector> threeSum(vector& nums) {
int n = nums.size();
if(n < 3) return {};
vector> result;
sort(nums.begin(), nums.end());
for(int i = 0; i < n-2; ++i){
if(i == 0 || nums[i] != nums[i-1]){
int j = i + 1, k = n-1;
while(j < k){
int sum = nums[i] + nums[j] + nums[k];
if(sum == 0){
result.push_back({nums[i], nums[j], nums[k]});
while(j < k && nums[j] == nums[j+1]) j++;
while(j < k && nums[k] == nums[k-1]) k--;
j++; k--;
}
else if (sum > 0) k--;
else j++;
}
}
}
return result;
}
58. (LC 16) 3Sum Closest
--------------------------
`16. 3Sum Closest `_
*(Medium)*
| **Keys**:
| -sort
| -three pointers, diff var
| -if threeSum > Greater than target, move RP
::
# <----|
# [-4,-1,1,2]
# R
-if threeSum < Less than target, move MidPoint ::
# |--->
# [-4,-1,1,2]
# M
**Solutions**::
### My V3 (LC accepted, 16, 74%)
def threeSumClosest(a, t):
a.sort()
ans = 0
dif = float("inf")
for lp in range(len(a) - 2):
rp = len(a) - 1
mp = lp + 1
while mp < rp:
summing = sum([a[lp], a[mp], a[rp]])
cur_dif = abs(summing - t)
if cur_dif < dif:
dif = cur_dif
ans = summing
if summing > t:
rp -= 1
elif summing < t:
mp += 1
else:
return t
return ans
::
# My V (Stdlib)
import itertools as it
def sum_closest(a, t):
combos = it.combinations(a, 3)
sums = [sum(c) for c in combos]
ans = sums[0]
dif = abs(t - ans)
for s in sums:
if abs(t - s) < dif:
ans = s
return ans
nums = [-1, 2, 1, -4]
target = 1
print(sum_closest(nums, target)) # 2
Solutions Time: O(n^2)::
### 1
def threeSumClosest(nums, target):
N = len(nums)
nums.sort()
res = float('inf') # sum of 3 numbers
for t in range(N):
i, j = t + 1, N - 1
while i < j:
_sum = nums[t] + nums[i] + nums[j]
if abs(_sum - target) < abs(res - target):
res = _sum
if _sum > target:
j -= 1
elif _sum < target:
i += 1
else:
return target
return res
### 2 (pretty much the same)
def threeSumClosest(num, target):
num.sort()
mindiff = 100000
res = 0
for i in range(len(num)):
left = i + 1
right = len(num) - 1
while left < right:
sum = num[i] + num[left] + num[right]
diff = abs(sum - target)
if diff < mindiff:
mindiff = diff
res = sum
if sum == target:
return sum
elif sum < target:
left += 1
else:
right -= 1
return res
59. (LC 989) Add to Array-Form of Integer
-------------------------------------------
*(Easy)*
The array-form of an integer num is an array representing its digits in left to right order.
For example, for num = 1321, the array form is [1,3,2,1].
Given num, the array-form of an integer, and an integer k, return the array-form of the integer num + k.
| Example 1:
| Input: num = [1,2,0,0], k = 34
| Output: [1,2,3,4]
| Explanation: 1200 + 34 = 1234
| Example 2:
| Input: num = [2,7,4], k = 181
| Output: [4,5,5]
| Explanation: 274 + 181 = 455
| Example 3:
| Input: num = [2,1,5], k = 806
| Output: [1,0,2,1]
| Explanation: 215 + 806 = 1021
::
### My v
def add_to_array(a, n):
a = [0] + a
for i in range((len(a) - 1), -1, -1):
a[i] = a[i] + (n % 10) #4+(181%10)=4+1=5
a[i - 1] += a[i] // 10 #7+5//10, i.e. +carry
a[i] = a[i] % 10 #if there was carry on a[i], chop it off
n = n // 10 #chop of right digit from 181, leaving 18
if a[0] == 0:
return a[1:]
return a
num = [2, 7, 4]
k = 181
print(add_to_array(num, k)) #[4, 5, 5]
### Solution 1
# (operation on array)
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
s = ""
for i in num:
s += str(i)
answer = int(s) + k
return list("".join(str(answer))) #why not list(str(answer))
# Using list comprehension
class Solution:
def addToArrayForm(self, A: List[int], K: int) -> List[int]:
return [int(x) for x in str(int(''.join(str(x) for x in A))+K)]
| ``divmod(a,b)``
| Given two numbers (a=what you want to divide, b=divide by )
| Gives as result (quotient, remainder)
>>> divmod(26, 5)
(5, 1)
::
### Solution 2
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
i, carry = len(num) - 1, 0
ans = []
while i >= 0 or k or carry:
carry += (0 if i < 0 else num[i]) + (k % 10)
carry, v = divmod(carry, 10)
ans.append(v)
k //= 10
i -= 1
return ans[::-1]
| **Explained**
| E.g., Input: num = [1,2,0,0], k = 34
| i, carry = len(num) - 1, 0
| # We start at the LSB, i.e. last index i of array 'num'.
| Here at first iteration i=4
| Set carry to 0.
| while i >= 0 or k or carry:
| # Because we need to carry on if k > number in array.
| 1)No worries, we won't do i=-1 lookups in array nums. carry=0 if i < 0.
| 2)Strangely we set carry to be the result of normal sum of num[i] + k%10.
| FYI k%10 is the LSB of k, here 34%10=4
| First loop, i=3, carry = num[3] + 4 = 4
| We set this right in the next step.
| 3)
| carry, v = divmod(carry, 10)
>>> divmod(4, 10)
(0, 4)
| Now carry is 0, v=4
| FYI, if instead of 4, we had 18, then we get our carry=1 with:
>>> divmod(18, 10)
(1, 8)
| 4)
| ans.append(v)
| 5)
| k //= 10
| i -= 1
| Remove k's LSB (34//10 = 3)
| Move to the next index.
| Next we will be adding 3 to num[3-1].
::
### Solution 3
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
for i in reversed(range(len(num))):
k, num[i] = divmod(num[i] + k, 10)
while k > 0:
num = [k % 10] + num
k //= 10
return num
60. (LC 419) Battleships in a Board
-------------------------------------
`419. Battleships in a Board `_
Medium
| **Solution 1**
| **Keys:**
-Just check for each cell that has 'X' if the cell or the cell
also has 'X'. Means you already counted that 'X', so you can continue.
::
class Solution(object):
def countBattleships(self, board):
"""
:type board: List[List[str]]
:rtype: int
"""
h = len(board)
w = len(board[0]) if h else 0
ans = 0
for x in range(h):
for y in range(w):
if board[x][y] == 'X':
if x > 0 and board[x - 1][y] == 'X': #if there is a ship above
continue
if y > 0 and board[x][y - 1] == 'X': #if there is a sip to the left
continue
ans += 1
return ans
| Note,
| h (height) is x (first index in matrix)
| **Solution 2**
| If you overdid problems on graphs.
::
### My V (LC accepted 5, 8% slow)
class Solution:
def countBattleships(self, board: List[List[str]]) -> int:
rows = len(board)
cols = len(board[0])
visited = set()
ships = 0
def dfs(r,c):
if r not in range(rows) or c not in range(cols) or (
board[r][c] == '.' or (r,c) in visited):
return
visited.add((r,c))
dfs(r, c+1)
dfs(r, c-1)
dfs(r+1, c)
dfs(r-1, c)
for r in range(rows):
for c in range(cols):
if board[r][c] == 'X' and (r,c) not in visited:
dfs(r,c)
ships +=1
return ships
61. (LC 121) Best Time to Buy and Sell Stock
------------------------------------------------
`121. Best Time to Buy and Sell Stock `_
*(Easy)*
In short: buy and sell once, return max profit.
You are given an array prices where prices[i] is the price of a given stock on the ith day.
You want to maximize your profit by choosing a single day to buy one stock and
choosing a different day in the future to sell that stock.
Return the maximum profit you can achieve from this transaction.
If you cannot achieve any profit, return 0.
Example 1:
Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.
Example 2:
Input: prices = [7,6,4,3,1]
Output: 0
Explanation: In this case, no transactions are done and the max profit = 0.
::
### My V
def buy_sell(a):
max_pofit, min_price = 0, a[0]
for p in a:
min_price = min(min_price, p)
max_pofit = max(max_pofit, p - min_price)
return max_pofit
### Solution 1
class Solution(object):
def maxProfit(self, prices):
if len(prices) == 0:
return 0
### NOTE : we define 1st minPrice as prices[0]
minPrice = prices[0]
maxProfit = 0
### NOTE : we only loop prices ONCE
for p in prices:
# only if p < minPrice, we get minPrice
if p < minPrice:
minPrice = p
### NOTE : only if p - minPrice > maxProfit, we get maxProfit
elif p - minPrice > maxProfit:
maxProfit = p - minPrice
return maxProfit
### Other Solutions
class Solution:
def maxProfit(self, prices: List[int]) -> int:
ans, mi = 0, inf
for v in prices:
ans = max(ans, v - mi)
mi = min(mi, v)
return ans
class Solution(object):
# @param prices, a list of integers
# @return an integer
def maxProfit(self, prices):
max_profit, min_price = 0, float("inf")
for price in prices:
min_price = min(min_price, price)
max_profit = max(max_profit, price - min_price)
return max_profit
62. (LC 309) Best Time to Buy and Sell Stock with Cooldown
------------------------------------------------------------
`309. Best Time to Buy and Sell Stock with Cooldown
`_
*(Medium)*
::
# 1
class Solution:
def maxProfit(self, prices: List[int]) -> int:
sell = 0
hold = -math.inf
prev = 0
for price in prices:
cache = sell
sell = max(sell, hold + price)
hold = max(hold, prev - price)
prev = cache
return sell
# 2
class Solution:
def maxProfit(self, prices: List[int]) -> int:
f, f0, f1 = 0, 0, -prices[0]
for x in prices[1:]:
f, f0, f1 = f0, max(f0, f1 + x), max(f1, f - x)
return f0
# 3 Dynamic programming, O(n) [:ref:`10 `]::
from typing import List
def maxProfit(prices: List[int]) -> int:
# State: Buying or Selling?
# If Buy -> i + 1
# If Sell -> i + 2 # +2 because +cooldown day
dp = {} # key=(i, buying) val=max_profit, dp implements cashing
def dfs(i, buying):
if i >= len(prices):
return 0
if (i, buying) in dp:
return dp[(i, buying)]
cooldown = dfs(i + 1, buying)
if buying:
buy = dfs(i + 1, not buying) - prices[i]
dp[(i, buying)] = max(buy, cooldown)
else:
sell = dfs(i + 2, not buying) + prices[i]
dp[(i, buying)] = max(sell, cooldown)
return dp[(i, buying)]
return dfs(0, True)
prices = [1, 2, 3, 0, 2]
print(maxProfit(prices))
63. (LC 122) Best Time to Buy and Sell Stock II
-------------------------------------------------
`122. Best Time to Buy and Sell Stock II
`_
*(Medium)*
| Key is that you can buy and sell on the same day.
| -Basically you can sell each time you meet a higher price.
| -If successful sell, then set = (so sell and buy on the same day).
| -Add up the results.
| E.g. prices=[1,2,3,4,5]
| You don't have to look for the best option, which is here buy at 1, sell at 5.
| You can buy at 1, sell at 2. Then buy at 2, sell at 3 etc.
**Solution 1** [:ref:`2 `] ::
### Solution 1
from typing import List
import itertools
def maxProfit(prices: List[int]) -> int:
return sum(max(0, b - a) for a, b in itertools.pairwise(prices))
prices = [7,1,5,3,6,4]
print(maxProfit(prices)) # 7
| # tools
| ``itertools.pairwise(iterable)``
| Roughly equivalent to:
| pairwise('ABCDEFG') --> AB BC CD DE EF FG
**Solution 2** [:ref:`10 `] ::
### Solution 2
class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_profit = 0
for i in range(1, len(prices)):
if prices[i] > prices[i-1]:
max_profit += prices[i] - prices[i-1]
return max_profit
**My V** (LC accepted 50, 70%) ::
class Solution:
def maxProfit(self, prices: List[int]) -> int:
cur_min = prices[0]
total_profit = 0
for price in prices:
cur_min = min(cur_min, price)
profit = price - cur_min
if profit > 0:
cur_min = price
total_profit += profit
return total_profit
Emulating as close as possible the classic buy-sell stock.
64. (LC 1014) Best Sightseeing Pair
-------------------------------------
`1014. Best Sightseeing Pair `_
*(Medium)*
| # In short
| Given an array, return the highest
| values[i] + values[j] + i - j
| # Keys
| i - j is the distance between the sightseeing spots.
::
### Solution 1
class Solution:
def maxScoreSightseeingPair(self, A: List[int]) -> int:
n = len(A)
pre = A[0] + 0
res = 0
for i in range(1, n):
res = max(res, pre + A[i] - i)
pre = max(pre, A[i] + i)
return res
# The same (breaking down the steps)
from typing import List
def f(A: List[int]) -> int:
n = len(A)
pre = A[0] + 0
res = 0
for i in range(1, n):
cur_res = pre + A[i] - i
res = max(res, cur_res)
possible_pre = A[i] + i
pre = max(pre, possible_pre)
return res
| # Explained solution 1
| ``res = max(res, pre + A[i] - i)``
| Final response, check if we found a greater
| (previous spot + current spot - distance between them)
| # - i, + i confusion
| it might seem unfair that in
| ``res = max(res, pre + A[i] - i)``
| We each time subtract the full index, not the net distance (i - j).
| But actually it is because in the second line:
| ``pre = max(pre, A[i] + i)``
| A[i] + i
| + i means the value at i will carry with it its distance.
| So if our new previous = value + 3 (it is at index 3).
| Then the next time we calculate response, e.g. at i=4,
| max(res, value+3 - 4)
| We see that if they are only 1 place apart, we end up subtracting only that 1, not 4.
| ==>previous CARRIES its distance with its value.
| E.g. A = [2,4,10]
| pre=A[0]=2, res=0
| i=1
| res=max(0, 2+4-1), res=5
| pre=max(2, 4+1), pre=5
| i=2
| res=max(5, 5+10-2), res=13 (so really 5+10-2=4+10-1)
| pre=max(5, 10+2), pre=12 ==>10 carries the weight of where it is at, i.e. index 2
65. (LC 605) Can Place Flowers
---------------------------------
| *(Easy)*
| 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.
| Example 1:
| Input: flowerbed = [1,0,0,0,1], n = 1
| Output: true
| Example 2:
| Input: flowerbed = [1,0,0,0,1], n = 2
| Output: false
::
### My V
def can_plant(a, n):
a = [0] + a + [0]
cnt = 0
for i in range(1, len(a) - 1):
if not a[i] & 1:
if a[i - 1] == 0 and a[i + 1] == 0:
cnt += 1
a[i] = 1
return cnt >= n
flowerbed = [1, 0, 0, 0, 1]
print(can_plant(flowerbed, 1)) # True
print(can_plant(flowerbed, 2)) # False
### Solution 1
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
flowerbed = [0] + flowerbed + [0]
for i in range(1, len(flowerbed) - 1):
if sum(flowerbed[i - 1 : i + 2]) == 0:
flowerbed[i] = 1
n -= 1
return n <= 0
| ### Explained
| (See explanation for solution 2 in addition.)
| #Here we check if values at [i=1, i=2, i=3] all add up to 0, none is set to 1 in one go.
| #We also account for the fact that we may have A = [0,0,1,0,1],
| so we may plant at i=0.
| Because we do:
| flowerbed = [0] + flowerbed + [0]
| We start the loop for i in range(1..), but we actually start at original i=0,
| which is now i=1, because we prepended with\appended to array 0s.
::
### Solution 2
class Solution(object):
def canPlaceFlowers(self, flowerbed, n):
"""
:type flowerbed: List[int]
:type n: int
:rtype: bool
"""
for i, num in enumerate(flowerbed):
if num == 1: continue
if i > 0 and flowerbed[i - 1] == 1: continue
if i < len(flowerbed) - 1 and flowerbed[i + 1] == 1: continue
flowerbed[i] = 1
n -= 1
return n <= 0
| ### Explained
| 1) If num at i is 1, continue
| 2) Check adjacent values to the left and right of the current i, see if they are 1,
| then we cannot plant.
| if i > 0 and flowerbed[i - 1] == 1: continue
| # If it is not the first element (at i=0), check that element to the left (i-1)
| is not 1. Else continue the loop.
| if i < len(flowerbed) - 1 and flowerbed[i + 1] == 1: continue
| # If we are looking not at the last element of the array (len(A)-1),
| (then it has no elements to the right)
| then check if element to the right (at i+1) is 1.
::
### Solution 3
class Solution(object):
def canPlaceFlowers(self, flowerbed, n):
"""
:type flowerbed: List[int]
:type n: int
:rtype: bool
"""
flowerbed = [0] + flowerbed + [0]
N = len(flowerbed)
res = 0
for i in range(1, N - 1):
if flowerbed[i - 1] == flowerbed[i] == flowerbed[i + 1] == 0:
res += 1
flowerbed[i] = 1
return res >= n