小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目描述
给你一个由非负整数
a1, a2, ..., an组成的数据流输入,请你将到目前为止看到的数字总结为不相交的区间列表。实现
SummaryRanges类:
SummaryRanges()使用一个空数据流初始化对象。void addNum(int val)向数据流中加入整数val。int[][] getIntervals()以不相交区间[starti, endi]的列表形式返回对数据流中整数的总结。
示例1 :
输入:
["SummaryRanges", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals"] [[], [1], [], [3], [], [7], [], [2], [], [6], []]
输出:
[null, null, [[1, 1]], null, [[1, 1], [3, 3]], null, [[1, 1], [3, 3], [7, 7]], null, [[1, 3], [7, 7]], null, [[1, 3], [6, 7]]]
解释:
SummaryRanges summaryRanges = new SummaryRanges(); summaryRanges.addNum(1); // arr = [1] summaryRanges.getIntervals(); // 返回 [[1, 1]] summaryRanges.addNum(3); // arr = [1, 3] summaryRanges.getIntervals(); // 返回 [[1, 1], [3, 3]] summaryRanges.addNum(7); // arr = [1, 3, 7] summaryRanges.getIntervals(); // 返回 [[1, 1], [3, 3], [7, 7]] summaryRanges.addNum(2); // arr = [1, 2, 3, 7] summaryRanges.getIntervals(); // 返回 [[1, 3], [7, 7]] summaryRanges.addNum(6); // arr = [1, 2, 3, 6, 7] summaryRanges.getIntervals(); // 返回 [[1, 3], [6, 7]]
思路:hashMap+链表
分析:套用上链表,在用排序哈希表维护一个每个不相交区间的边界,即左边界对应最小值,右边界对应最大值。
class SummaryRanges {
static class Node {
int val;
Node next;
}
static class IntervalNode {
int start;
int end;
IntervalNode next;
}
Node node;
public SummaryRanges() {
}
public void addNum(int val) {
if (node == null) {
// 添加第一个节点
node = new Node();
node.val = val;
return;
} else if (node.val > val) {
// 小于第一个节点数字,作为首节点插入
Node firstNode = new Node();
firstNode.val = val;
firstNode.next = node;
node = firstNode;
return;
} else if (node.val == val) {
// 与首节点相等
return;
}
Node curNode = node;
while (curNode.next != null) {
if (curNode.next.val == val) {
// 与当前节点相等
return;
} else if (curNode.next.val > val) {
// 如果下一个节点数字比插入数字大,在当前节点后面插入节点
Node node = new Node();
node.val = val;
node.next = curNode.next;
curNode.next = node;
return;
} else {
curNode = curNode.next;
}
}
// 数字最大,添加到最后一个节点
Node newNode = new Node();
newNode.val = val;
curNode.next = newNode;
}
public int[][] getIntervals() {
if (node == null) {
return null;
}
Node curNode = node;
int length = 1;
IntervalNode intervalNode = new IntervalNode();
intervalNode.start = curNode.val;
intervalNode.end = curNode.val;
IntervalNode curIntervalNode = intervalNode;
while ((curNode = curNode.next) != null) {
if (curNode.val == curIntervalNode.end + 1) {
curIntervalNode.end = curNode.val;
} else {
IntervalNode next = new IntervalNode();
next.start = curNode.val;
next.end = curNode.val;
curIntervalNode.next = next;
length++;
curIntervalNode = curIntervalNode.next;
}
}
int[][] ints = new int[length][2];
IntervalNode copyNode = intervalNode;
for (int i = 0; i < length; i++) {
ints[i] = new int[]{copyNode.start, copyNode.end};
copyNode = copyNode.next;
}
return ints;
}
}