728x90
/* 슬라이딩 윈도우 */
슬라이딩 윈도우는 전체 데이터에서 특정 구간의 값을 지속적으로 계산하는 문제에서 사용됩니다. 구간의 시작과 끝을 조정하며 데이터 처리를 최소화해 효율성을 높입니다.
작동 방식
- 처음에 윈도우 내 데이터를 모두 처리해 초기 값을 계산합니다.
- 이후 윈도우를 한 칸씩 이동하며, 새로 들어오는 데이터를 추가하고, 이전 데이터를 제거합니다.
- 반복적으로 윈도우를 이동하면서 원하는 값을 갱신합니다.
/* 슬라이딩 윈도우의 장점 */
- 효율성: 중복 계산을 방지하며, 연속된 구간에 대해 데이터를 재활용하여 O(n)의 시간복잡도를 가질 수 있습니다.
- 간결성: 문제를 단순화하고 가독성을 높이는 코드 작성이 가능합니다.
- 다양한 활용: 배열, 문자열, 또는 다른 선형 데이터에서 부분합, 최댓값, 최솟값, 특정 패턴 탐색 등 다양한 문제에 응용 가능합니다.
/* 고정 크기 윈도우 */
// 배열에서 연속된 k개의 숫자의 합 계산.
public int maxSum(int[] arr, int k) {
int n = arr.length;
int maxSum = 0;
int windowSum = 0;
// 첫 윈도우 합 계산
for (int i = 0; i < k; i++) {
windowSum += arr[i];
}
maxSum = windowSum;
// 슬라이딩 윈도우
for (int i = k; i < n; i++) {
windowSum += arr[i] - arr[i - k];
maxSum = Math.max(maxSum, windowSum);
}
return maxSum;
}
/* 가변 크기 윈도우 */
// 배열에서 합이 특정 값 이상이 되는 가장 작은 윈도우 크기
public int minWindowSize(int[] arr, int target) {
int n = arr.length;
int minLength = Integer.MAX_VALUE;
int windowSum = 0;
int left = 0;
for (int right = 0; right < n; right++) {
windowSum += arr[right];
// 윈도우의 합이 목표를 초과하면 크기를 줄임
while (windowSum >= target) {
minLength = Math.min(minLength, right - left + 1);
windowSum -= arr[left++];
}
}
return minLength == Integer.MAX_VALUE ? 0 : minLength;
}
/* 프로그래머스 연속 부분 수열 합의 개수 */
public int circularSubarraySums(int[] elements) {
Set<Integer> uniqueSums = new HashSet<>();
int n = elements.length;
for (int length = 1; length <= n; length++) {
int sum = 0;
// 첫 번째 부분합 계산
for (int i = 0; i < length; i++) {
sum += elements[i];
}
uniqueSums.add(sum);
// 슬라이딩 윈도우로 나머지 부분합 계산
for (int start = 1; start < n; start++) {
sum -= elements[(start - 1) % n];
sum += elements[(start + length - 1) % n];
uniqueSums.add(sum);
}
}
return uniqueSums.size();
}
728x90
'CS지식' 카테고리의 다른 글
[알고리즘] 프로그래머스 '의상' (0) | 2025.01.10 |
---|---|
[알고리즘] Tajan Algorithm. 타잔 알고리즘 SCC (0) | 2025.01.02 |
[운영체제] 병행성 (0) | 2024.09.03 |
[운영체제] Paging 과 Multi-Level Paging (0) | 2024.08.27 |
[운영체제] 메모리 가상화 - Segmentation (0) | 2024.08.22 |