Skip to content

Commit f147478

Browse files
authored
Merge pull request soapyigu#360 from soapyigu/Sort
Add a solution to Range Module
2 parents 5bbe4e5 + 3503f3b commit f147478

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

Sort/RangeModule.swift

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* Question Link: https://leetcode.com/problems/range-module/
3+
* Primary idea: Sort ranges by left, query using binary search, remove to handle 4 cases separately.
4+
* Time Complexity: add - O(nlogn), query - O(logn), remove - O(n), Space Complexity: O(n)
5+
*
6+
*/
7+
8+
class RangeModule {
9+
10+
var sortedRanges: [(Int, Int)]
11+
12+
init() {
13+
sortedRanges = [(Int, Int)]()
14+
}
15+
16+
func addRange(_ left: Int, _ right: Int) {
17+
sortRanges(for: (left, right))
18+
}
19+
20+
func queryRange(_ left: Int, _ right: Int) -> Bool {
21+
// binary search
22+
var l = 0, r = sortedRanges.count - 1
23+
24+
while l <= r {
25+
let m = (r - l) / 2 + l
26+
27+
if sortedRanges[m].0 <= left && sortedRanges[m].1 >= right {
28+
return true
29+
} else {
30+
if sortedRanges[m].0 > right {
31+
r = m - 1
32+
} else if sortedRanges[m].1 < left {
33+
l = m + 1
34+
} else {
35+
return false
36+
}
37+
}
38+
}
39+
40+
return false
41+
}
42+
43+
func removeRange(_ left: Int, _ right: Int) {
44+
var idx = 0
45+
46+
while idx < sortedRanges.count {
47+
let range = sortedRanges[idx]
48+
49+
if isOverlap(range, (left, right)) {
50+
if range.0 >= left && range.1 <= right {
51+
sortedRanges.remove(at: idx)
52+
} else if range.0 < left && range.1 > right {
53+
sortedRanges.remove(at: idx)
54+
sortedRanges.insert((right, range.1), at: idx)
55+
sortedRanges.insert((range.0, left), at: idx)
56+
idx += 2
57+
} else if range.1 <= right {
58+
sortedRanges[idx].1 = left
59+
idx += 1
60+
} else {
61+
sortedRanges[idx].0 = right
62+
idx += 1
63+
}
64+
} else {
65+
idx += 1
66+
}
67+
}
68+
}
69+
70+
71+
private func sortRanges(for newRange: (Int, Int)) {
72+
sortedRanges.append(newRange)
73+
74+
sortedRanges.sort {
75+
$0.0 < $1.0
76+
}
77+
78+
var res = [(Int, Int)]()
79+
80+
for range in sortedRanges {
81+
guard let last = res.last else {
82+
res.append(range)
83+
continue
84+
}
85+
86+
if range.0 > last.1 {
87+
res.append(range)
88+
} else {
89+
res.removeLast()
90+
res.append((last.0, max(last.1, range.1)))
91+
}
92+
}
93+
94+
sortedRanges = res
95+
}
96+
97+
private func isOverlap(_ l: (Int, Int), _ r: (Int, Int)) -> Bool {
98+
return !(l.0 >= r.1 || r.0 >= l.1)
99+
}
100+
}

0 commit comments

Comments
 (0)