|
6 | 6 |
|
7 | 7 | # @lc code=start
|
8 | 8 | # TAGS: Sliding Window, Two Pointers
|
| 9 | +from typing import List |
| 10 | + |
| 11 | + |
9 | 12 | class Solution:
|
10 |
| - # 6465 ms, 5.02%. Time: O(N^2). Space: O(N) |
11 |
| - def longestOnes(self, A: List[int], K: int) -> int: |
12 |
| - |
13 |
| - def sum_from_i(i, K): |
14 |
| - k = K |
15 |
| - rv = 0 |
16 |
| - for val, length in group[i:]: |
17 |
| - if val == 1: |
18 |
| - rv += length |
19 |
| - elif val == 0 and length <= k: |
20 |
| - k -= length |
21 |
| - rv += length |
22 |
| - elif val == 0 and length > k: |
23 |
| - rv += k |
24 |
| - k = 0 |
25 |
| - break |
26 |
| - return rv, k |
27 |
| - |
28 |
| - group = [(i, len(list(g))) for i, g in itertools.groupby(A)] |
29 |
| - |
30 |
| - ans = 0 |
31 |
| - for i in range(len(group)): |
32 |
| - rv, k = sum_from_i(i, K) |
33 |
| - if i > 0 and group[i - 1][1] > k: |
34 |
| - rv += k |
35 |
| - ans = max(ans, rv) |
36 |
| - |
| 13 | + # 652 ms, 41.04% |
| 14 | + # Easy to understand solition |
| 15 | + def longestOnes(self, A: List[int], k: int) -> int: |
| 16 | + ptr = ans = 0 |
| 17 | + for i, n in enumerate(A): |
| 18 | + if not n: |
| 19 | + while not k: |
| 20 | + k += A[ptr] == 0 |
| 21 | + ptr += 1 |
| 22 | + k -= 1 |
| 23 | + ans = max(ans, i + 1 - ptr) |
37 | 24 | return ans
|
38 |
| - # 552 ms, 94.19%. Time: O(N). Space: O(1). Sliding Window |
| 25 | + |
| 26 | + # 564 ms, 86.48% |
| 27 | + # Over simplified of the version above. Very clever but hard to understand |
| 28 | + # We never decrease the size of the window |
| 29 | + # K is used as the offset. |
| 30 | + # if K is positive, we can always increase the window size |
| 31 | + # if K is negative, we increase K (if applicable) and this it as offset at the end |
| 32 | + # at some point, K might turn back to positive again, at which time the offset reduce to 0 |
39 | 33 | def longestOnes(self, A: List[int], K: int) -> int:
|
40 | 34 | left = 0
|
41 | 35 | for right in range(len(A)):
|
42 |
| - K -= 1 - A[right] |
| 36 | + K -= A[right] == 0 |
| 37 | + |
43 | 38 | if K < 0:
|
44 |
| - K += 1 - A[left] |
| 39 | + K += A[left] == 0 |
45 | 40 | left += 1
|
46 |
| - |
47 |
| - # we can return this because we never decrease the size, only increase of not change. |
| 41 | + |
48 | 42 | return right - left + 1
|
49 | 43 |
|
50 | 44 | # @lc code=end
|
51 |
| - |
0 commit comments