Given a binary array nums
and an integer k
, return the maximum number of consecutive 1
's in the array if you can flip at most k
0
's.
For example:
nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
Output: 6
Explanation: [1,1,1,0,0,1,1,1,1,1,1]
nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3
Output: 10
Explanation: [0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
What is the most efficient algorithm to solve this problem? What is the time and space complexity of your solution? Please provide code. Consider edge cases.
We can iterate through all possible subarrays and, for each subarray, count the number of zeros. If the number of zeros is less than or equal to k
, we update the maximum length found so far. This approach is straightforward but inefficient.
Code (Python):
def longest_ones_brute_force(nums, k):
max_len = 0
for i in range(len(nums)):
for j in range(i, len(nums)):
subarray = nums[i:j+1]
zeros = subarray.count(0)
if zeros <= k:
max_len = max(max_len, len(subarray))
return max_len
Time Complexity: O(n^3), where n is the length of the input array. This is because we have nested loops to generate all subarrays (O(n^2)), and for each subarray, we count the zeros (O(n)).
Space Complexity: O(1), excluding the space used by the input array.
A more efficient approach is to use the sliding window technique. We maintain a window and expand it to the right. If the number of zeros in the window exceeds k
, we shrink the window from the left until the number of zeros is back within the limit. The maximum window size encountered during this process is the answer.
Algorithm:
left
and right
, to 0.zeros
to keep track of the number of zeros in the current window.right
pointer.nums[right]
is 0, increment zeros
.zeros
is greater than k
, increment the left
pointer. If nums[left]
is 0, decrement zeros
.Code (Python):
def longest_ones_sliding_window(nums, k):
left = 0
zeros = 0
max_len = 0
for right in range(len(nums)):
if nums[right] == 0:
zeros += 1
while zeros > k:
if nums[left] == 0:
zeros -= 1
left += 1
max_len = max(max_len, right - left + 1)
return max_len
Time Complexity: O(n), where n is the length of the input array. We iterate through the array once with the right
pointer, and the left
pointer can only move up to n times in the worst case.
Space Complexity: O(1), as we only use a constant amount of extra space.
nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
left = 0
, right = 0
, zeros = 0
, max_len = 0
right
:
right = 0
, nums[0] = 1
, zeros = 0
, max_len = 1
right = 1
, nums[1] = 1
, zeros = 0
, max_len = 2
right = 2
, nums[2] = 1
, zeros = 0
, max_len = 3
right = 3
, nums[3] = 0
, zeros = 1
, max_len = 4
right = 4
, nums[4] = 0
, zeros = 2
, max_len = 5
right = 5
, nums[5] = 0
, zeros = 3
zeros > k
, so increment left
:
left = 0
, nums[0] = 1
left = 1
, nums[1] = 1
left = 2
, nums[2] = 1
left = 3
, nums[3] = 0
, zeros = 2
, left = 4
right = 6
, nums[6] = 1
, zeros = 2
, max_len = 6
right = 7
, nums[7] = 1
, zeros = 2
, max_len = 6
right = 8
, nums[8] = 1
, zeros = 2
, max_len = 6
right = 9
, nums[9] = 1
, zeros = 2
, max_len = 6
right = 10
, nums[10] = 0
, zeros = 3
zeros > k
, so increment left
:
left = 4
, nums[4] = 0
, zeros = 2
, left = 5
max_len = 6
Return 6.