3
Map<Integer, int[]> st;4
Map<Integer, int[]> end;6
int[][] prev = new int[0][];7
Set<Integer> seen = new HashSet<>();10
public SummaryRanges() {12
end = new HashMap<>();13
pending = new HashSet<>();16
public void addNum(int val) { // [TC: O(1)]17
if (!seen.contains(val)) { // only add if not seen.18
pending.add(val); // pending processing list23
getIntervals() { // [TC: O(pending list length (= k)) best case (all merges), O(n)+O(klogk)24
// worst case (all inserts)]25
Set<int[]> addSet = new HashSet<>();26
for (int n : pending) {27
if (st.containsKey(n + 1)29
n - 1)) { // merge intervals on both ends, a new interval form -> add to addSet30
int[] s = st.get(n + 1);31
int[] e = end.get(n - 1);32
int[] m = new int[] {e[0], s[1]};37
s[0] = e[0] = INVALID;38
addSet.remove(s); // may be in addSet, remove them41
} else if (st.containsKey(n + 1)) { // merge with the next interval, no other action required.43
st.put(n, st.get(n + 1));45
} else if (end.containsKey(46
n - 1)) { // merge with the previous interval, no other action required.48
end.put(n, end.get(n - 1));50
} else { // new interval -> add to AddSet51
int[] m = new int[] {n, n};59
pending.clear(); // remember to clear the pending list.61
if (!addSet.isEmpty()) { // IF there is no new intervals to insert, we SKIP this.62
List<int[]> addList = new ArrayList<>(addSet);63
addList.sort(Comparator.comparingInt(o -> o[0]));64
int i = 0, j = 0; // two pointers because both prev & addList are sorted.65
List<int[]> ans = new ArrayList<>();66
while (i < prev.length || j < addList.size()) {67
if (i < prev.length && prev[i][0] == INVALID) {69
} else if (j == addList.size() || i < prev.length && prev[i][0] < addList.get(j)[0]) {71
} else if (i == prev.length || prev[i][0] > addList.get(j)[0]) {72
ans.add(addList.get(j++));75
prev = ans.toArray(new int[0][]);