Minimum Size Subarray Sum - LeetCode
Can you solve this real interview question? Minimum Size Subarray Sum - Given an array of positive integers nums and a positive integer target, return the minimal length of a subarray whose sum is greater than or equal to target. If there is no such subarr
leetcode.com
문제
- Input
양의정수 배열 nums, 양의 정수 target - Output
합이 target 이상인 부분 배열중 길이가 가장 짧은 것의 길이 반환, 없다면 0 반환
시간 복잡도
※1초에 1억 번을 대략적인 기준으로 삼는다.
| O(1) : 크게 상관없음 | O(log n) : 크게 상관없음 | O(n) : 100'000'000 (1억) | O(n log n) : 1'000'000 (100만) | O(n^2) : 10'000 (1만) |
$1 \le n \le 100'000$으로, $n \log n$ 부터 고려가능하다.
해결 과정
연속된 부분 배열을 다루어야하기 때문에 자연스럽게 투 포인터를 생각했다.
투 포인터 안에 있는 배열의 합을 sum이라고 한다면, 대강 생각해 보았을 때 target과 sum의 관계를 이용하여 둘 중 어떤 게 크다면 왼쪽을 움직이고, 반대면 오른쪽을 움직인다던지, 이런 느낌처럼 해보면 괜찮겠다고 생각하여 더 자세히 생각해 봤다.
그래서 우선 투 포인터가 모두 0부터 시작한다고 가정할 때, 처리해야 하는 두 가지의 경우를 생각했다.
- target <= sum
정답의 후보가 된다. 하지만 이 이상 오른쪽 포인터를 늘려봤자, 현재의 정답 후보보다 길이가 길기 때문에 의미가 없다.
따라서 현재 길이를 정답 후보로 갱신하고, 더 짧은 구간을 찾기 위해 왼쪽 포인터를 증가시킨다. - sum < target
sum을 키워야 한다 => 부분배열을 늘려야 한다
왼쪽 포인터를 감소하여 부분배열을 늘리는 것은 이미 탐색했던 구간이 다시 포함되기 때문에,
오른쪽 포인터를 증가하여 부분배열의 크기를 늘린다.
그리고 아래와 같은 수도 코드를 작성했다.
WHILE (r < nums.size)
{
IF (총합이 target 이상일 때)
ret업데이트
++l
sum 업데이트
IF (총합이 target 미만일 때)
++r
sum 업데이트
}
해당 방법은 최대 2n이므로 $O(n)$의 복잡도를 가지기 때문에 충분히 통과 가능한 복잡도이며,
마지막으로 $1 \le nums[i] \le 10'000$으로, 최대 합이 1'000'000'000이 되어 int로 충분함을 확인했다.
구현
추가적으로 작성한 것들 중에 input으로 들어오는 nums에 -1을 추가하였는데, 이는 Out of range를 막기 위한 조건문을 고민하다가 그냥 쓰레기 값 하나를 추가하면 편하지 않을까?라는 생각에 시도했는데 잘 동작되었다.
하지만 생각해 보면 엄청 효율적이지는 않은 것 같다..ㅎ
그리고 std::min연산의 예외를 처리하기 위해 ret을 INT_MAX로 정의했다.
int minSubArrayLen(int target, vector<int>& nums)
{
int n = nums.size();
nums.push_back(-1);
int l = 0; int r = 0;
int ret = INT_MAX;
int sum = nums[0];
while (r < n)
{
// 총합이 target 이상일 때
if (target <= sum)
{
ret = std::min(ret, r - l + 1);
sum -= nums[l];
++l;
}
// 총합이 target 이하일 때
else
{
++r;
sum += nums[r];
}
}
return (ret == INT_MAX) ? 0 : ret;
}
되돌아보기
문제 잘못 이해
target과 정확히 맞는 경우인 줄 알아서 초반에 허튼짓을 했다;
문제를 좀 더 자세히 읽어야겠다.
가능한 경우
target과 sum의 두 가지 관계를 고려해 봤었는데, 사실 이전에 어떻게 조건문을 작성하지 머리를 싸매다 '될 수 있는 경우를 작성해 보자! 하고' 정리했었다.
정리하고 나니까 좀 더 명확해져서 코드를 작성하기 쉬운 면이 있었다.
다음에는 가능한 경우를 먼저 고려해 보면 좋을 듯하다.
개선 코드
좀 더 깔끔한 버전이다.
r은 무조건 마지막까지 증가되어야 함을 이용하여 for문으로 정의했다.
int minSubArrayLen(int target, vector<int>& nums)
{
int n = nums.size();
int l = 0;
int sum = 0;
int ret = INT_MAX;
for (int r = 0; r < n; ++r)
{
sum += nums[r];
while (target <= sum)
{
ret = min(ret, r - l + 1);
sum -= nums[l];
++l;
}
}
return ret == INT_MAX ? 0 : ret;
}
'코딩 테스트 > 알고리즘 풀이' 카테고리의 다른 글
| 🟠[Leet code - 3] Longest Substring Without Repeating Characters ★ ✅ (0) | 2026.05.19 |
|---|---|
| 🔴[Leet code - 76] Minimum Window Substring ❌✅ (0) | 2026.05.19 |
| 🟠[Leet code - 424] Longest Repeating Character Replacement ✅ (0) | 2026.05.14 |
| 🟠[Leet code - 567] Permutation in String ✅ (0) | 2026.05.12 |
| 🟠[Leet code - 322] Coin Change ❌✅ (0) | 2026.05.11 |
| 🟠[Leet code - 15] 3Sum ❌ (0) | 2026.05.07 |
| 🟠[Leet code - 11] Container With Most Water ✅ (0) | 2026.05.06 |
| 🟠[Leet code - 167] Two Sum II - Input Array Is Sorted ✅ (0) | 2026.05.04 |