LeetCode 567 Permutation in String 풀이: 문자 빈도 슬라이딩 윈도우
LeetCode 567 Permutation in String에서 s1과 같은 길이의 창을 움직이며 26개 문자 빈도를 비교한다. 나가고 들어오는 문자만 갱신해 O(n) 시간과 O(1) 공간에 순열 부분 문자열을 찾는다.
구간을 효율적으로 옮기며 부분 배열의 상태를 관리하는 문제를 다룬다. 현재 3개의 풀이가 있다.
LeetCode 567 Permutation in String에서 s1과 같은 길이의 창을 움직이며 26개 문자 빈도를 비교한다. 나가고 들어오는 문자만 갱신해 O(n) 시간과 O(1) 공간에 순열 부분 문자열을 찾는다.
프로그래머스 선인장 숨기기에서 각 칸의 강수 시점을 기록하고, 가로·세로 단조 덱으로 직사각형의 최솟값을 구한다. 최대 500,000칸을 O(mn)에 처리한다.
프로그래머스 보석 쇼핑에서 슬라이딩 윈도우로 현재 구간의 보석 종류와 개수를 관리한다. 모든 종류를 포함하는 가장 짧은 구간과 시작 위치 조건을 찾는다.
필요한 주제만 펼쳐서 연속 구간을 효율적으로 관리하고, 매번 다시 계산하는 작업을 줄이는 방법을 학습할 수 있습니다.
슬라이딩 윈도우는 배열이나 문자열의 연속된 구간을 현재 상태로 유지하면서 경계를 이동하는 기법입니다. 새 구간을 처음부터 다시 계산하는 대신, 빠져나가는 값과 들어오는 값만 반영합니다.
구간 길이가 `k`로 정해져 있으면 첫 윈도우를 한 번 계산하고, 이후 매 단계에서 이전 구간의 왼쪽 원소를 빼고 새 오른쪽 원소를 더합니다.
window_sum = sum(nums[:k])
best = window_sum
for right in range(k, len(nums)):
window_sum += nums[right]
window_sum -= nums[right - k]
best = max(best, window_sum)합계나 평균, 특정 길이의 부분 문자열 빈도처럼 같은 크기의 구간을 모두 확인하는 문제에 적합합니다. 각 원소를 상수 번씩만 처리하므로 전체 계산을 `O(n)`에 할 수 있습니다.
구간의 길이가 조건에 따라 달라지면 `right`를 늘려 새 원소를 포함하고, 조건을 만족하지 않거나 가능한 구간을 더 줄일 수 있을 때 `left`를 이동합니다.
각 포인터가 왼쪽에서 오른쪽으로 한 번씩만 이동하는 구조라면 안쪽에 `while`문이 있어도 전체 시간은 보통 `O(n)`입니다.
문자열 `s1`의 순열은 길이가 `len(s1)`이고 문자별 등장 횟수가 같은 부분 문자열입니다. 따라서 `s2`를 길이 `len(s1)`인 고정 윈도우로 이동하면서 빈도 상태를 비교하면 됩니다.