[Algorithm][LeetCode 560] Subarray Sum Equals K ๋ฌธ์ ํ์ด - ๋์ ํฉ๊ณผ Hash Map ํ์ฉ๋ฒ
๐ข LeetCode 560. Subarray Sum Equals K ๋ฌธ์ ํ์ด (with ๋์ ํฉ + ํด์๋งต)
์ต๊ทผ Leetcode 2845. Count of Interesting Subarrays ๋ฌธ์ ๋ฅผ ํ๋ค๊ฐ ๋งํ๋ ๋ถ๋ถ์ด ์์๋๋ฐ, ์ ํ๋ธ์์ ํํธ๋ฅผ ์ฐพ์๋ณด๋ค๊ฐ ์๋ ์์์ ๋ฐ๊ฒฌํ์ต๋๋ค.
How to solve Count of Interesting Subarrays (Leetcode 2845)
์ด ์์์์๋ Leetcode 560๋ฒ๊ณผ 523๋ฒ ๋ฌธ์ ๋ฅผ ๋จผ์ ํ์ด๋ณด๋ฉด ์ดํด๊ฐ ์ ๋๋ค๊ณ ์ถ์ฒํ๋๋ผ๊ณ ์.
๊ทธ๋์ ๋จผ์ Leetcode 560. Subarray Sum Equals K ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์์ต๋๋ค.
๐ข ๋ฌธ์ ์ค๋ช
Given an array of integers
nums
and an integerk
,
return the total number of subarrays whose sum equals tok
.
- Subarray: ์ฐ์๋ ์์๋ค์ ๋ถ๋ถ ๋ฐฐ์ด (๋น์ด ์์ผ๋ฉด ์ ๋จ).
- Example 1:
Input: nums = [1,1,1], k = 2 Output: 2
- Example 2:
Input: nums = [1,2,3], k = 3 Output: 2
- Constraints:
1 <= nums.length <= 2 * 10โด -1000 <= nums[i] <= 1000 -10โท <= k <= 10โท
๐ ์ ๊ทผ ๋ฐฉ๋ฒ (์ด 3๊ฐ์ง)
1๏ธโฃ Brute Force ๋ฐฉ์ (O(N²), O(1))
๊ฐ์ฅ ์ง๊ด์ ์ธ ๋ฐฉ๋ฒ์
๋๋ค.
๋ชจ๋ subarray๋ฅผ ํ๋ํ๋ ํ์ธํ๋ฉด์ ํฉ์ด k์ธ ๊ฒฝ์ฐ๋ฅผ ์ธ๋ ๋ฐฉ์์
๋๋ค.
const subarraySum = function(nums, k) {
let count = 0;
for (let i = 0; i < nums.length; i++) {
let sum = 0;
for (let j = i; j < nums.length; j++) {
sum += nums[j];
if (sum === k) count++;
}
}
return count;
}
- ์๊ฐ ๋ณต์ก๋: O(N²)
- ๊ณต๊ฐ ๋ณต์ก๋: O(1)
โ ๋ฐฐ์ด์ด ๊ธธ์ด์ง์๋ก ๋งค์ฐ ๋๋ ค์ง๋๋ค.
2๏ธโฃ Prefix Sum + 2์ค ๋ฃจํ (O(N²), O(N))
๋์ ํฉ(Prefix Sum)์ ๋จผ์ ๊ณ์ฐํด๋๊ณ ,
๊ตฌ๊ฐํฉ์ prefixSum[i] - prefixSum[j]
๋ก ๊ตฌํ๋ ๋ฐฉ์์
๋๋ค.
const subarraySum = function(nums, k) {
let prefix = 0;
let count = 0;
const preCalculatedSum = nums.map((num) => {
prefix += num;
return prefix;
});
for (let i = 0; i < preCalculatedSum.length; i++) {
if (preCalculatedSum[i] === k) {
count++;
}
for (let j = 0; j < i; j++) {
if (preCalculatedSum[i] - preCalculatedSum[j] === k) {
count++;
}
}
}
return count;
};
- ์๊ฐ ๋ณต์ก๋: O(N²)
- ๊ณต๊ฐ ๋ณต์ก๋: O(N)
โ ๏ธ Brute Force๋ณด๋ค๋ ์ค๋ณต ๊ณ์ฐ์ด ์ค์์ง๋ง, ์๊ฐ ๋ณต์ก๋๋ ๊ทธ๋๋ก์ ๋๋ค.
3๏ธโฃ Prefix Sum + Hash Map (O(N), O(N)) โญ๏ธ
์ด ๋ฌธ์ ์ ์ต์ ํ๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค.
โ ํต์ฌ ์์ด๋์ด
- ๊ตฌ๊ฐํฉ์ ๋์ ํฉ์ ์ฐจ์ด๋ก ์ ์ ์์ต๋๋ค.
- ๊ตฌ๊ฐ [i, j]์ ํฉ =
prefixSum[j] - prefixSum[i - 1]
- ์ด ๊ณต์์ ๋ณํํ๋ฉด:
prefixSum[j] - k = prefixSum[i - 1]
- ํ์ฌ๊น์ง ๋์ ํฉ์ด
prefixSum[j]
์ธ๋ฐ,
๊ณผ๊ฑฐ์prefixSum[i - 1]
์ด๋ผ๋ ๋์ ํฉ์ด ์์๋ค๋ฉด, ๊ทธ ๊ตฌ๊ฐํฉ์ k๊ฐ ๋ฉ๋๋ค. - ์ด์ ๋์ ํฉ์ Hash Map์ ์ ์ฅํด๋๊ณ ,
๋งค ์๊ฐprefixSum[j] - k
๊ฐ ๊ณผ๊ฑฐ์ ์์๋์ง ๋น ๋ฅด๊ฒ ํ์ธํ๋ฉด ๋ฉ๋๋ค.
๐ก prefixSum[-1] = 0์ 1๋ก ๊ฐ์ ํ๋ ์ด์
- ์๋ฌด ์ซ์๋ ๊ณ ๋ฅด์ง ์๊ณ ๋ํ์ง ์์ ์ํ๋ฅผ
prefixSum[-1] = 0
์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. - ์์:
nums = [1, -1, 0]
,k = 0
- ํฉ์ด 0์ด ๋๋ subarray:
- [1, -1]
- [1, -1, 0]
- [0]
- ์ด์ฒ๋ผ ๋งจ ์์์ ์์ํ๋ ๊ตฌ๊ฐ์ ๊ตฌํ๋ ค๋ฉด,
prefixSum[-1] = 0
์ด๋ผ๋ ์ง์ ์ด ์์ด์ผ ํฉ๋๋ค. - ๊ทธ๋์ ์ด๊ธฐ ์ค์ ์ผ๋ก
map.set(0, 1)
์ ํด์ค๋๋ค.
๐ข ์ฝ๋
const subarraySum = function(nums, k) {
const map = new Map();
map.set(0, 1); // prefixSum[-1] = 0์ 1๋ฒ ์๋ค๊ณ ๊ฐ์
let sum = 0;
let count = 0;
for (let num of nums) {
sum += num;
const target = sum - k;
if (map.has(target)) {
count += map.get(target); // ์ด์ ์ ๋์๋ target๋งํผ count ์ฆ๊ฐ
}
map.set(sum, (map.get(sum) || 0) + 1); // ํ์ฌ prefix sum ์ ์ฅ
}
return count;
};
- ์๊ฐ ๋ณต์ก๋: O(N)
- ๊ณต๊ฐ ๋ณต์ก๋: O(N)
โ ๋์ ํฉ์ ์ด์ฉํ๋ฉด์, ๊ณผ๊ฑฐ ๋์ ํฉ์ Map์ผ๋ก ๊ด๋ฆฌํด์ ๋น ๋ฅด๊ฒ ๊ตฌ๊ฐํฉ์ ์ฐพ๋ ๋ฐฉ์์ ๋๋ค.
๐ ์ ๋ฆฌ
๋ฐฉ๋ฒ | ์๊ฐ ๋ณต์ก๋ | ๊ณต๊ฐ ๋ณต์ก๋ | ํน์ง |
---|---|---|---|
Brute Force | O(N²) | O(1) | ๋จ์ํ๊ณ ์ง๊ด์ ์ด์ง๋ง ๋๋ฆผ |
Prefix Sum + 2์ค ๋ฃจํ | O(N²) | O(N) | ๋์ ํฉ ์ฌ์ฉ, ์ค๋ณต ๊ณ์ฐ ์ผ๋ถ ๊ฐ์ |
Prefix Sum + Hash Map (์ถ์ฒ) | O(N) | O(N) | ์ต์ ํ๋ ๋ฐฉ์, ์ค๋ฌด์์๋ ์์ฃผ ์ฌ์ฉ |
๐งญ ๋ง๋ฌด๋ฆฌ
์ด ๋ฌธ์ ๋ฅผ ํตํด:
- ๋์ ํฉ(Prefix Sum)
- Hash Map์ ์ด์ฉํ ๊ตฌ๊ฐํฉ ์ต์ ํ
๊ฐ๋ ์ ์ฐ์ตํ ์ ์์์ต๋๋ค.
์ด์ ์ด ๋ฌธ์ ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก,
Leetcode 2845. Count of Interesting Subarrays ๋ฌธ์ ๋ ์กฐ๊ธ ๋ ์ดํดํ๊ธฐ ์ฌ์์ง ๊ฒ ๊ฐ์ต๋๋ค.
โ ํจ๊ป ๋ณด๋ฉด ์ข์ ๋ฌธ์
- Leetcode 523. Continuous Subarray Sum (์ด ๋ฌธ์ ๋ ๋์ ํฉ + ๋๋จธ์ง ํ์ฉ)