|
| 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