부분합이 특정 값을 넘는 가장 짧은 연속된 부분 배열의 길이를 구하는 문제입니다.
단순히 합만 구하는 것이 아니라, 길이까지 고려해야 하기에 효율적인 알고리즘이 필요합니다.
이 글에서는 Brute-force 접근 → 슬라이딩 윈도우 최적화 과정을 거쳐,
Dart로 완성도 높은 코드를 작성하고 이해하는 과정을 함께합니다.
📘 문제 설명
양의 정수 배열 nums와 목표값 target이 주어질 때,
합이 target 이상이 되는 연속된 부분 배열(subarray) 중에서
가장 짧은 길이를 반환하라.
없으면 0을 반환한다.
❌ Brute-force 접근 (비효율)
int minLength = nums.length + 1;
for (int i = 0; i < nums.length; i++) {
int sum = 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
if (sum >= target) {
minLength = min(minLength, j - i + 1);
break;
}
}
}
- 시간복잡도: O(n²) → 큰 입력에서는 시간 초과 가능성 있음
- 매 i마다 전체 탐색 → 비효율적
✅ 최적화: 슬라이딩 윈도우
슬라이딩 윈도우는 합이 기준 이상일 때 길이를 최소화하는 문제에 딱 적합합니다.
💻 Dart 코드
class Solution {
int minSubArrayLen(int target, List<int> nums) {
int n = nums.length;
int left = 0;
int sum = 0;
int minLength = n + 1;
for (int right = 0; right < n; right++) {
sum += nums[right];
while (sum >= target) {
minLength = minLength < (right - left + 1) ? minLength : (right - left + 1);
sum -= nums[left];
left++;
}
}
return minLength == n + 1 ? 0 : minLength;
}
}
🧠 코드 풀이
구간 설명
sum += nums[right] | 윈도우 오른쪽 확장하며 합 누적 |
while (sum >= target) | 조건 만족 시 길이 갱신 시도 |
minLength = ... | 현재 길이가 기존 최소보다 짧으면 갱신 |
sum -= nums[left]; left++ | 왼쪽을 줄이며 더 짧은 조합 시도 |
종료 후 리턴 | 조건 만족한 적 없으면 0, 있으면 최소 길이 |
🌊 슬라이딩 윈도우 흐름 예시
입력: target = 7, nums = [2,3,1,2,4,3]
step | left | right | sum | 조건 만족 | 윈도우 길이 | minLength |
1 | 0 | 0 | 2 | ❌ | - | ∞ |
2 | 0 | 1 | 5 | ❌ | - | ∞ |
3 | 0 | 2 | 6 | ❌ | - | ∞ |
4 | 0 | 3 | 8 | ✅ | 4 | 4 |
5 | 1 | 3 | 6 | ❌ | - | 4 |
6 | 1 | 4 | 10 | ✅ | 4 | 4 → 3 |
7 | 2 | 4 | 7 | ✅ | 3 | 3 → 2 |
8 | 3 | 4 | 4 | ❌ | - | 2 |
9 | 3 | 5 | 7 | ✅ | 3 | 유지 |
10 | 4 | 5 | 3 | ❌ | - | 2 |
⏱ 시간 & 공간 복잡도
항목 복잡도 설명
시간 | O(n) | 각 포인터가 최대 한 번씩만 이동 |
공간 | O(1) | 추가 공간 없음 |
✨ 실전 팁 요약
- “조건 만족하는 최소 길이” 문제는 무조건 슬라이딩 윈도우 먼저 떠올릴 것
- 오른쪽으로 확장하면서 합을 만들고, 왼쪽을 줄여가며 최소 길이 갱신
- 투 포인터 + 조건 기반 줄이기 전략은 여러 문제에 응용 가능
LeetCode, Dart 알고리즘, 슬라이딩 윈도우, 투 포인터, 부분합 문제
'Algorithm > LeetCode' 카테고리의 다른 글
Dart-LeetCode 11번: Container With Most Water — 투 포인터 전략으로 풀어보기 (0) | 2025.04.02 |
---|---|
[LeetCode 167] Two Sum II - Input Array Is Sorted (0) | 2025.03.28 |
[LeetCode 392] Is Subsequence - 부분 수열 판별하기 (0) | 2025.03.27 |
[LeetCode 125] Valid Palindrome - 유효한 회문 판단하기 (0) | 2025.03.26 |
[LeetCode 68] Text Justification - 텍스트 양쪽 정렬 (0) | 2025.03.25 |