Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 유니온파인드
- 다익스트라
- 완전탐색
- 알고리즘
- 기본유형
- Java
- 다시보기
- 코테
- database
- 백준
- 싸피
- 완탐
- JUnit
- 알고리즘기본개념
- 코딩테스트실력진단
- 그래프
- 자바
- DP
- SSAFY
- SWEA
- Spring
- Union Find
- JPA
- BFS
- 그리디
- 부분수열의합2
- 트러블슈팅
- DFS
- 코딩테스트
- 코드트리
Archives
- Today
- Total
HwangHub
[Java/투포인터] LeetCode 992. Subarrays with K Different Integers 본문
workspace/알고리즘
[Java/투포인터] LeetCode 992. Subarrays with K Different Integers
HwangJerry 2024. 3. 30. 21:39🤔 Intuition
체감상 어려워서 답을 참고했다. 막상 답을 보면 "간단하네..." 하는 문제를 마주하면 현타가 좀 오는데, 이번 문제도 그러했다.
counting array를 운영하는 부분수열 유형이므로 투포인터로 해결할 수 있음은 명료하다.
🔎 Algorithm & Complexity
* @algorithm two pointer
* @time O(N)
* @memory O(N)
👨🏻💻 Logic
직관적이면서 가장 빠른 풀이는 maxEnd와 minEnd를 운영하는 것이다. (3 ms)
- right pointer를 +1씩 옮겨가면서 정확히 K개의 distinct elements로 구성된 가장 작은 subarray를 먼저 찾고, (right=minEnd)
- righter pointer를 그 상황에서 distinct elements가 K개로 유지되는 한 +1씩 더 옮겨서 최대 길이를 찾는다. (right=maxEnd)
- 각 left에 대한 maxEnd - minEnd + 1가 distinct elements가 K개인 subarray의 경우의 수이다.
- 위 과정을 left++ 를 반복하며 구하면 된다.
import java.util.*;
class Solution {
public int subarraysWithKDistinct(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
int ans = 0, left = 0, right = 0;
while (right < nums.length) {
while (map.size() < k && right < nums.length) {
map.put(nums[right], map.getOrDefault(nums[right], 0) + 1);
right++;
}
// if distinct elements count == k : (below)
int maxEnd = right;
while (maxEnd < nums.length && map.getOrDefault(nums[maxEnd], 0) != 0) {
maxEnd++;
}
while (map.size() == k) {
ans += maxEnd - right + 1;
if (map.get(nums[left]) == 1) {
map.remove(nums[left]);
} else {
map.put(nums[left], map.get(nums[left]) - 1);
}
left++;
}
}
return ans;
}
}
조금 기발한 아이디어로 푸는 방법도 있었다. (46ms)
distinct elements의 개수가 K인 subarrays의 개수는 (distinct elements의 개수가 "최대" K개인 경우의 수) - (distinct elements의 개수가 "최대" K - 1개인 경우의 수)와 같다. 따라서 이를 구현하여 답안을 도출해낼 수 있다.
import java.util.*;
/**
* @return the number of "good subarrays" // good array : an array where the
* number of different integers in that array is exactly k
*/
class Solution {
public int subarraysWithKDistinct(int[] nums, int k) {
return (int) (subarraysWithAtMostK(nums, k) - subarraysWithAtMostK(nums, k - 1));
}
public long subarraysWithAtMostK(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
int left = 0;
int right = 0;
long ans = 0;
while (right < nums.length) {
map.put(nums[right], map.getOrDefault(nums[right], 0) + 1);
while (map.size() > k) {
map.put(nums[left], map.get(nums[left]) - 1);
if (map.get(nums[left]) == 0) {
map.remove(nums[left]);
}
left++;
}
ans += right - left + 1; // the length of the subarray equals the number of subarray of each case
right++;
}
return ans;
}
}
'workspace > 알고리즘' 카테고리의 다른 글
[Java/다익스트라] 백준 4485. 녹색 옷 입은 애가 젤다지? (0) | 2024.04.02 |
---|---|
[Java/수학] SWEA. 원점으로 집합 (1) | 2024.04.02 |
[Java/투포인터] 리트코드 2962. Count Subarrays Where Max Element Appears at Least K Times (0) | 2024.03.30 |
[Java/투포인터] 코드트리. 1이 k개 이상 존재하는 부분 수열 (1) | 2024.03.29 |
[Java/스택] 백준 5397. 키로거 (0) | 2024.03.28 |
Comments