Skip to content

Commit 2268284

Browse files
committed
Solution: insert interval
1 parent 5facfcc commit 2268284

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

insert-interval/flynn.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
풀이
3+
- newInterval의 start와 end에 대해 각각 이진탐색을 진행하여 insert할 index를 찾아낼 수 있습니다
4+
- index의 앞뒤 interval과 newInterval을 비교하여 merge 여부를 판별하면 문제에서 원하는 배열을 만들 수 있습니다
5+
Big O
6+
- N: 주어진 배열 intervals의 길이
7+
- Time complexity: O(N)
8+
- 이진 탐색 -> O(logN)
9+
- append(res, ...) -> O(N)
10+
- O(N + logN) = O(N)
11+
- Space complexity: O(N)
12+
- 반환하는 배열 res의 공간 복잡도를 고려하면 O(N)
13+
*/
14+
15+
func insert(intervals [][]int, newInterval []int) [][]int {
16+
n := len(intervals)
17+
// base case
18+
if n == 0 {
19+
return append(intervals, newInterval)
20+
}
21+
// 이진탐색 함수
22+
// isStart: newInterval의 start를 탐색할 땐 true, end를 탐색할 땐 false
23+
// target보다 큰 값 중에서 가장 작은 index를 반환함
24+
var binarySearch func(int, bool) int
25+
binarySearch = func(target int, isStart bool) int {
26+
lo := 0
27+
hi := len(intervals)
28+
for lo < hi {
29+
mid := lo + (hi-lo)/2
30+
if isStart {
31+
if intervals[mid][0] < target {
32+
lo = mid + 1
33+
} else {
34+
hi = mid
35+
}
36+
} else {
37+
if intervals[mid][1] < target {
38+
lo = mid + 1
39+
} else {
40+
hi = mid
41+
}
42+
}
43+
}
44+
return lo
45+
}
46+
47+
start := binarySearch(newInterval[0], true)
48+
// newInterval의 시작 지점이 intervals[start-1]의 끝 지점보다 작거나 같으면 merge해야 함
49+
mergeStart := start > 0 && newInterval[0] <= intervals[start-1][1]
50+
end := binarySearch(newInterval[1], false) - 1
51+
// newInterval의 끝 지점이 intervals[end+1]의 시작 지점보다 크거나 같으면 merge해야 함
52+
mergeEnd := end+1 < n && newInterval[1] >= intervals[end+1][0]
53+
54+
// -Go에서의 최적화를 위한 코드입니다-
55+
resCapacity := n + 1
56+
if mergeStart {
57+
resCapacity--
58+
}
59+
if mergeEnd {
60+
resCapacity--
61+
}
62+
// -----------------------------
63+
res := make([][]int, 0, resCapacity)
64+
// newInterval이 들어갈 index보다 앞 부분의 값들을 res에 append
65+
if mergeStart {
66+
res = append(res, intervals[:start-1]...)
67+
} else {
68+
res = append(res, intervals[:start]...)
69+
}
70+
// newInterval을 res에 append
71+
// mergeStart, mergeEnd 여부에 따라 병합할지 그대로 넣을지 판단
72+
if mergeStart && mergeEnd {
73+
res = append(res, []int{intervals[start-1][0], intervals[end+1][1]})
74+
} else if mergeStart {
75+
res = append(res, []int{intervals[start-1][0], newInterval[1]})
76+
} else if mergeEnd {
77+
res = append(res, []int{newInterval[0], intervals[end+1][1]})
78+
} else {
79+
res = append(res, newInterval)
80+
}
81+
// newInterval이 들어갈 index보다 뒷 부분의 값들을 res에 append
82+
if mergeEnd {
83+
res = append(res, intervals[end+2:]...)
84+
} else {
85+
res = append(res, intervals[end+1:]...)
86+
}
87+
88+
return res
89+
}

0 commit comments

Comments
 (0)