February 13, 2025
I completed the LeetCode 150! Since then, I haven't stopped practicing. I want to master common algorithms and feel confident for future interviews.
For this problem, I started with this greedy solution. We always flip a zero if
we haven't done so k
times. Each step, we check if our count is a new maximum.
If we reach a zero and used all our flips, we reset our count and flips.
We start counting again from this position.
1class Solution:2 def longestOnes(self, nums: List[int], k: int) -> int:3 largest = float('-inf')4 count = 05 flipped = 06 for num in nums:7 if num == 1:8 count += 19 if num == 0 and flipped < k:10 count += 111 flipped += 112 elif num == 0 and flipped == k:13 largest = max(largest, count)14 count, flipped = 1, 11516 return largest
This works for the first example:
Input: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
Output: 6 (correct!)
However, for the second example, it fails to connect the first two strings of ones.
Input: nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3
Output: 9 (incorrect, expected 10.)
To fix this, we will have to alter our algorithm to conditionally flip a zero. My idea is to apply our previous algorithm at each step.
1class Solution:2 def longestOnes(self, nums: List[int], k: int) -> int:3 largest = float('-inf')45 def countOnes(start):6 count = 07 flipped = 08 for i in range(start, len(nums)):9 num = nums[i]10 if num == 1:11 count += 112 if num == 0 and flipped < k:13 choice = i14 count += 115 flipped += 116 elif num == 0 and flipped == k:17 return count18 return count1920 for i in range(len(nums)):21 largest = max(largest, countOnes(i))2223 return largest
Unfortunately, this is inefficient, but it works. It has a quadratic time complexity of O(n) = (N^2 + n) / 2, also known as the nth triangle number.
Rather we should make this algorithm into a sliding-window algorithm. When we reach the end of a series of ones, we want to slide our window by moving our start to the second flip we made by removing our first flip along with any tail attached to it. To do this, we create a queue and add our tail each time we flip and set the new tail to 0.
1from collections import deque2class Solution:3 def longestOnes(self, nums: List[int], k: int) -> int:4 largest = float('-inf')5 count, tail = 0, 06 tails = deque([])7 for i, num in enumerate(nums):8 count += 19 tail += 110 if num == 0:11 if tails and len(tails) == k:12 count -= tails.popleft()13 elif not k:14 count = 015 tails.append(tail)16 tail = 017 largest = max(largest, count)18 return largest
This has a time complexity of O(n) = n at the tradeoff of space complexity being O(n) = n compared to O(n) = 1 for previous solutions.
LeetCode 120. Triangle
LeetCode 32. Longest Valid Parantheses