포스트

[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 라이센스를 따릅니다.