누적합 + 해시맵을 사용하는 대표적인 패턴 문제입니다.
✅ 문제 요약
- 배열 nums와 정수 k가 주어질 때,
연속된 구간(subarray)의 합이 k가 되는 경우의 수를 구하라.
from collections import defaultdict
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
count = 0 # 정답: 합이 k인 서브어레이의 개수
prefixSum = 0 # 누적합 (0부터 현재 인덱스까지의 합)
prefixCount = defaultdict(int) # key: 누적합, value: 그 누적합이 몇 번 나왔는지 저장
prefixCount[0] = 1 # ❗️ 중요 포인트 ❗️
# 누적합이 k인 서브어레이가 [0:i] 범위일 때를 처리하려면
# prefixSum - k == 0 이 되어야 하고,
# 그 0이 prefixCount에 있어야 count += 1 이 가능해짐
# 즉, 아무것도 더하지 않은 상태에서 0이라는 누적합이 한 번 있었던 셈!
for num in nums:
prefixSum += num # 현재까지의 누적합 계산
# prefixSum - k가 과거에 몇 번 나왔는지를 확인
# 그 횟수만큼 (과거에 그런 누적합이 있었던 시점 이후부터 지금까지의) 부분합이 k라는 의미
count += prefixCount[prefixSum - k]
# 현재 누적합을 prefixCount에 기록
# (다음에 나올 수 있는 prefixSum - k 체크를 위해)
prefixCount[prefixSum] += 1
return count
✅ 직관적 흐름 정리
- prefixSum = 지금까지 합
- prefixSum - k = 과거에 이 값이 있었다면 → 그 이후부터 지금까지의 합은 k
- prefixCount[prefixSum - k] = 그 과거 누적합이 몇 번 있었는지
- 그만큼 count에 더함
1. Brute Force
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
res = 0
for i in range(len(nums)):
sum = 0
for j in range(i, len(nums)):
sum += nums[j]
if sum == k:
res += 1
return res
Time & Space Complexity
- Time complexity: O(n^2)
- Space complexity: O(1)
2. Hash Map
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
res = curSum = 0
prefixSums = { 0 : 1 }
for num in nums:
curSum += num
diff = curSum - k
res += prefixSums.get(diff, 0)
prefixSums[curSum] = 1 + prefixSums.get(curSum, 0)
return res
Time & Space Complexity
- Time complexity: O(n)
- Space complexity: O(n)
'LeetCode > Grind169' 카테고리의 다른 글
| 1. Two Sum (0) | 2025.04.22 |
|---|---|
| [LinkedLists: Fast and Slow Pointers] 287. Find the Duplicate Number ★★★★★ (1) | 2025.04.06 |
| 424. Longest Repeating Character Replacement ★★★★★ (0) | 2025.04.04 |
| Graphs(싸이클확인, Union Find): 323. Number of Connected Components in an Undirected Graph ★★★★★ (0) | 2025.01.28 |
| Graphs(Valid Tree: 싸이클 탐지, 연결성): 261. Graph Valid Tree ☆★★★★ (0) | 2025.01.27 |