You are given a 0-indexed integer array nums. A subarray of nums is called continuous if:
- Let i, i + 1, ..., j be the indices in the subarray. Then, for each pair of indices i <= i1, i2 <= j, 0 <= |nums[i1] - nums[i2]| <= 2.
Return the total number of continuous subarrays.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: nums = [5,4,2,4]
Output: 8
Explanation:
Continuous subarray of size 1: [5], [4], [2], [4].
Continuous subarray of size 2: [5,4], [4,2], [2,4].
Continuous subarray of size 3: [4,2,4].
Thereare no subarrys of size 4.
Total continuous subarrays = 4 + 3 + 1 = 8.
It can be shown that there are no more continuous subarrays.
Example 2:
Input: nums = [1,2,3]
Output: 6
Explanation:
Continuous subarray of size 1: [1], [2], [3].
Continuous subarray of size 2: [1,2], [2,3].
Continuous subarray of size 3: [1,2,3].
Total continuous subarrays = 3 + 2 + 1 = 6.
출처 : https://leetcode.com/problems/continuous-subarrays/description/
풀이
function continuousSubarrays(nums: number[]): number {
let sum = 0
let start = 0
let map = new Map()
for(let end = 0; end < nums.length; end++) {
map.set(nums[end], (map.get(nums[end]) || 0) + 1) // optimistically grow array
// window is invalid, shrink the array from left to make valid
while(Math.max(...map.keys()) - Math.min(...map.keys()) > 2) {
let count = map.get(nums[start]) - 1
if (count === 0) {
map.delete(nums[start])
} else {
map.set(nums[start], count)
}
start++
}
// count the valid subarrays
sum += (end - start + 1)
}
return sum
};
배열 nums에서 조건을 만족하는 "유효한" 연속 부분 배열(subarray)을 찾고, 그 부분 배열들의 개수를 구하는 문제를 해결하는 함수
단계별 동작 설명
초기화
- sum = 0: 유효한 부분 배열의 개수를 저장
- start = 0: 윈도우의 시작 인덱스를 의미
- map = {}: 현재 윈도우 내 숫자의 빈도를 저장하는 맵
1. 첫 번째 반복 (end = 0)
- 현재 숫자 nums[0] = 5이므로, map은 {5: 1}
- 현재 윈도우는 [5]이며, 최댓값과 최솟값은 모두 5. 따라서 차이는 5 - 5 = 0이므로 조건을 만족
- 현재 유효한 부분 배열의 개수는 end - start + 1 = 0 - 0 + 1 = 1
- sum += 1로 현재 sum은 1
2. 두 번째 반복 (end = 1)
- 현재 숫자 nums[1] = 4이므로, map은 {5: 1, 4: 1}
- 현재 윈도우는 [5, 4]이며, 최댓값은 5, 최솟값은 4. 차이는 5 - 4 = 1이므로 조건을 만족
- 현재 유효한 부분 배열의 개수는 end - start + 1 = 1 - 0 + 1 = 2
- sum += 2로 현재 sum은 3
3. 세 번째 반복 (end = 2)
- 현재 숫자 nums[2] = 2이므로, map은 {5: 1, 4: 1, 2: 1}
- 현재 윈도우는 [5, 4, 2]이며, 최댓값은 5, 최솟값은 2. 차이는 5 - 2 = 3이므로 조건을 만족하지 않음.
- 조건을 만족하게 하기 위해 start를 증가시켜 윈도우를 줄임.
- nums[start] = 5이므로, map에서 5의 빈도를 1 감소
- 결과적으로 map = {4: 1, 2: 1}
- 이제 윈도우는 [4, 2]가 되고, 최댓값은 4, 최솟값은 2로 차이는 4 - 2 = 2이므로 조건을 만족
- 현재 유효한 부분 배열의 개수는 end - start + 1 = 2 - 1 + 1 = 2
- sum += 2로 현재 sum은 5.
4. 네 번째 반복 (end = 3)
- 현재 숫자 nums[3] = 4이므로, map은 {4: 2, 2: 1}
- 현재 윈도우는 [4, 2, 4]이며, 최댓값은 4, 최솟값은 2. 차이는 4 - 2 = 2이므로 조건을 만족
- 현재 유효한 부분 배열의 개수는 end - start + 1 = 3 - 1 + 1 = 3
- sum += 3로 최종적으로 sum은 8
최종 결과
조건을 만족하는 모든 유효한 부분 배열들의 개수는 sum = 8
'LeetCode' 카테고리의 다른 글
| 2193. Minimum Number of Moves to Make Palindrome / TypeScipt (1) | 2024.09.23 |
|---|---|
| 1487. Making File Names Unique / TypeScript (1) | 2024.09.18 |
| 452. Minimum Number of Arrows to Burst Balloons / TypeScript (1) | 2024.09.12 |
| 1048. Longest String Chain / TypeScript (2) | 2024.09.10 |
| 2516. Take K of Each Character From Left and Right / TypeScript (0) | 2024.09.08 |