https://leetcode.com/problems/insert-interval/description/
코드설명
유니온파인드(UnionFind) OR 구현(Implementation) 를 활용합니다.
각 구간을 집합으로 살펴보고, 합치는 과정을 진행합니다.
이 방식으로 진행할 경우, 만약 interval이 [0,0] 이면 visited로 이 경우도 포함하도록 해야하는등 신경써야할 부분이 많습니다.
그대신에, 정답코드2번으로 진행합니다.
풀이는 아래와 같습니다.
current의 start, end 가 존재. interval 의 start, end가 존재. (이떄 interval은 current의 오른쪽에 존재하는 list를 의미)
만약 current.end >= interval.start 라면, 서로 포함되어 있는 상태이므로 current.end = Math.max(current.end, interval.end)로 범위를 갱신합니다. 이때 Max 함수를 사용하는 이유는, [3,5], [4,8] [6,7] 로 테스트해보면 알 수 있습니다.
-> [3, 8] [6, 7]
-> [3, 7] -> 더 작아지는 상황발생.
current[1] = Math.max(current[1], interval[1]);
이렇게 작성하면, 예외처리해야하는 경우가 없어집니다.
코드
유니온 파인드를 활용한 정답코드1입니다.
처음에 접근한 방식입니다. 상호배타적 집합 개념을 활용하여, 각 Interval을 집합으로 의식하면 해결가능합니다.
class Solution {
int[] parent = new int[100001];
boolean[] visited = new boolean[100001];
int minStart = 100001;
int maxEnd = 0;
public int[][] insert(int[][] intervals, int[] newInterval) {
minStart = Math.min(minStart, newInterval[0]);
maxEnd = Math.max(maxEnd, newInterval[1]);
for(int i=0; i<parent.length; i++){
parent[i] = i;
}
for(int i=0; i<intervals.length; i++){
int start = intervals[i][0];
int end = intervals[i][1];
visited[start] = true;
minStart = Math.min(minStart, start);
maxEnd = Math.max(maxEnd, end);
for(int j=start + 1; j<= end; j++){
visited[j] = true;
unionParent(start, j);
}
}
int start = newInterval[0];
int end = newInterval[1];
visited[start] = true;
for(int i=start + 1; i<=end; i++){
visited[i] = true;
unionParent(start, i);
}
for(int i=0; i<parent.length; i++){
findParent(i);
}
ArrayList<int[]> answer = new ArrayList<>();
int left = minStart;
while(left <= maxEnd){
int right = left;
int[] newArr = new int[2];
newArr[0] = left;
while(right <= maxEnd && parent[right] == parent[right + 1]){
right++;
}
newArr[1] = right;
if(left != right || (visited[left] == true) ) {
answer.add(newArr);
}
left = right;
left++;
}
return answer.toArray(new int[answer.size()][]);
}
int findParent(int x){
if(parent[x] == x) return x;
return parent[x] = findParent(parent[x]);
}
void unionParent(int a, int b){
a = findParent(a);
b = findParent(b);
if(a < b) parent[b] = a;
else if(b > a) parent[a] = b;
}
}
정답코드2입니다.
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> intervalList = new ArrayList<>(Arrays.asList(intervals));
intervalList.add(newInterval);
Collections.sort(intervalList, new Comparator<int[]>(){
@Override
public int compare(int[] o1, int[] o2){
return Integer.compare(o1[0], o2[0]);
}
});
List<int[]> res = new ArrayList<>();
int[] current = intervalList.get(0);
for(int i=1; i<intervalList.size(); i++){
int[] interval = intervalList.get(i);
if(current[1] >= interval[0]){
current[1] = Math.max(current[1], interval[1]);
// current[1] = interval[1];
} else {
res.add(current);
current = interval;
}
}
res.add(current);
return res.toArray(new int[res.size()][]);
}
}
'알고리즘 > LeetCode' 카테고리의 다른 글
[LeetCode] 64. Minimum Path Sum - 깊이우선탐색(DFS) + 동적계획법(Dynamic Programming) JAVA (0) | 2024.11.28 |
---|---|
[LeetCode] 50. Pow(x, n) - 분할정복(DivideAndConquer) + 수학(Math) JAVA (0) | 2024.11.24 |
[LeetCode] 74. Search a 2D Matrix - 이분탐색(BinarySearch) JAVA (0) | 2024.11.24 |
[LeetCode] 79. Word Search - 깊이우선탐색(DFS) + 문자열(String) JAVA (0) | 2024.11.24 |
[LeetCode] 61. Rotate List - 구현(Implementation) JAVA (0) | 2024.11.20 |