[leetcode] 슬라이딩 윈도우, 다른 접근
- 1 5
- nums[i] is either 0 or 1.
- 0
- 0의 리스트 만들기
- 예외처리 조기 리턴하기
- 첫 번째 슬라이딩 윈도우 계산
- 나머지 슬라이딩 윈도우 계산
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Solution:
def longestOnes(self, nums: List[int], k: int) -> int:
zeros = []
# 0의 인덱스 리스트를 만들고
for i in range(len(nums)):
if nums[i] == 0:
zeros.append(i)
# k개 이상의 0이 없으면 전체 배열
if k >= len(zeros):
return len(nums)
# k=0인 경우: 연속된 1의 최대 길이
if k == 0:
if len(zeros) == 0:
return len(nums)
max_count = 0
# 첫 번째 구간: 시작부터 첫 0 전까지
max_count = max(max_count, zeros[0])
# 중간 구간들: 0과 0 사이
for i in range(len(zeros) - 1):
count = zeros[i+1] - zeros[i] - 1
max_count = max(max_count, count)
# 마지막 구간: 마지막 0 다음부터 끝까지
max_count = max(max_count, len(nums) - zeros[-1] - 1)
return max_count
max_count = 0
# k개의 0을 포함하는 윈도우들을 확인
for i in range(len(zeros) - k + 1):
# i번째부터 i+k-1번째 0까지의 윈도우
start_zero = zeros[i] # 첫 번째 0의 위치
end_zero = zeros[i + k - 1] # k번째 0의 위치
# 윈도우 시작점: 첫 번째 0 이전까지 포함
window_start = 0 if i == 0 else zeros[i-1] + 1
# 윈도우 끝점: k번째 0 이후까지 포함
window_end = len(nums) - 1 if i + k == len(zeros) else zeros[i + k] - 1
count = window_end - window_start + 1
max_count = max(max_count, count)
return max_count
```
**핵심 아이디어:**
1. 0의 인덱스들을 `zeros` 배열에 저장
2. k개의 연속된 0들을 선택하는 모든 경우를 확인
3. 각 경우에서 그 k개의 0을 포함하여 최대한 확장할 수 있는 구간 계산
**Example 1 검증:**
```
nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
zeros = [3, 4, 5, 10]
i=0: zeros[0:2] = [3,4] → 구간 [0, 6) → length = 6
i=1: zeros[1:3] = [4,5] → 구간 [1, 7) → length = 6
i=2: zeros[2:4] = [5,10] → 구간 [2, 11) → length = 9
- right을 증가시켜서 윈도우 크기를 키움.
- 윈도우 오른쪽 끝이 0이면 zero count 증가시킴. zero count는 k 이하로 유지해야 함.
- zero count가 k보다 크면 left를 증가시켜서 zero count 개수 제한을 유지시킴.
- 최대 윈도우 길이를 갱신.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution:
def longestOnes(self, nums: List[int], k: int) -> int:
left = 0
zero_count = 0
max_length = 0
for right in range(len(nums)):
# 0을 만나면 카운트 증가
if nums[right] == 0:
zero_count += 1
# 0의 개수가 k를 초과하면 윈도우 축소
while zero_count > k:
if nums[left] == 0:
zero_count -= 1
left += 1
# 현재 윈도우 길이 갱신
max_length = max(max_length, right - left + 1)
return max_length
```
**동작 과정 (Example 1):**
```
nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
right=0: [1] → zero_count=0, length=1
right=1: [1,1] → zero_count=0, length=2
right=2: [1,1,1] → zero_count=0, length=3
right=3: [1,1,1,0] → zero_count=1, length=4
right=4: [1,1,1,0,0] → zero_count=2, length=5
right=5: [1,1,1,0,0,0] → zero_count=3 > k=2
left를 이동시켜 [0,0,0]로 축소 → zero_count=2
right=6: [0,0,1] → zero_count=2, length=3
...
시간 복잡도는 두 접근 다 O(n)
공간 복잡도는 표준 접근이 O(1), 내 접근이 O(z) - zeros 배열.
따라서 표준 접근이 코드의 간결성, 복잡도 면에서 모두 유리.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.