关闭

【leetcode】Data Stream as Disjoint Intervals

1361人阅读 评论(0) 收藏 举报
分类:

题目链接:https://leetcode.com/problems/data-stream-as-disjoint-intervals/

Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen so far as a list of disjoint intervals.

For example, suppose the integers from the data stream are 1, 3, 7, 2, 6, ..., then the summary will be:

[1, 1]
[1, 1], [3, 3]
[1, 1], [3, 3], [7, 7]
[1, 3], [7, 7]
[1, 3], [6, 7]

Follow up:

What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size?


思路:

建立一棵二叉搜索树,树的节点值用interval表示,其实就是类似于“区间树”节点值是个区间,这些区间不相交。建立树之后中序遍历输出结果。

插入的过程较为麻烦,插入需要考虑一个节点的两端点,情况较多,具体见代码注释。

插入时间复杂度为O(logn)。如果不用二查搜索树,直接用list做也可以,时间复杂度为O(n),leetcode也能ac。


算法:

public class SummaryRanges {
	Node root;

	/** Initialize your data structure here. */
	public SummaryRanges() {

	}

	public void addNum(int val) {
		if (root == null) {
			Interval v = new Interval(val, val);
			root = new Node(v, null, null);
		} else {
			searchAndAdjust(root, val);
		}
	}

	/**
	 * 搜索并调整树
	 */
	public void searchAndAdjust(Node node, int val) {
		// 若插入val在树左边,插入并调整
		if (node.val.start == val + 1) { // 若满足合并条件
			node.val.start = val;// 修改区间
			if (node.left != null) {// 调整左边
				if (node.left.right == null) {// 若左孩子的右孩子为空
					if (node.left.val.end + 1 == val) {// 若左孩子可以和父结点合并
						node.val.start = node.left.val.start;
						node.left = node.left.left;
					}
				} else {// 若左孩子的右孩子不为空
					Node tmp = node.left;
					Node parent = tmp;
					while (tmp.right != null) {// 一直走到node节点左孩子的最右节点
						parent = tmp;
						tmp = tmp.right;
					}
					if (tmp.val.end + 1 == val) {// 若可以和根节点合并
						node.val.start = tmp.val.start;
						parent.right = tmp.left;
					}
				}
			}
			return;
		}
		if (node.val.start > val + 1) {
			if (node.left == null) {// 无法合并区间时 新建节点
				Interval v = new Interval(val, val);
				Node newNode = new Node(v, null, null);
				node.left = newNode;
				return;
			} else {// 进入下一层搜索
				searchAndAdjust(node.left, val);
			}
		}
		// ======end
		// 若插入val在树右边,插入并调整,同上
		if (node.val.end == val - 1) {
			node.val.end = val;
			if (node.right != null) {
				if (node.right.left == null) {
					if (node.right.val.start - 1 == val) {
						node.val.end = node.right.val.end;
						node.right = node.right.right;
					}
				} else {
					Node tmp = node.right;
					Node parent = tmp;
					while (tmp.left != null) {// 一直走到node节点左孩子的最右节点
						parent = tmp;
						tmp = tmp.left;
					}
					if (tmp.val.start - 1 == val) {// 若可以和根节点合并
						node.val.end = tmp.val.end;
						parent.left = tmp.right;
					}
				}
			}
			return;
		}
		if (node.val.end < val - 1) {
			if (node.right == null) {
				Interval v = new Interval(val, val);
				Node newNode = new Node(v, null, null);
				node.right = newNode;
				return;
			} else {
				searchAndAdjust(node.right, val);
			}
		}

	}

	public List<Interval> getIntervals() {
		List<Interval> res = new ArrayList<Interval>();
		res = inorder(root, res);
		return res;
	}

	public List<Interval> inorder(Node node, List<Interval> res) {
		if (node != null) {
			res = inorder(node.left, res);
			res.add(node.val);
			res = inorder(node.right, res);
		}
		return res;
	}

	class Node {
		Interval val;
		Node left, right;

		public Node(Interval val, Node left, Node right) {
			this.val = val;
			this.left = left;
			this.right = right;
		}
	}
}


1
0
查看评论

[leetcode-352]Data Stream as Disjoint Intervals(java)

思路:采用一个TreeMap的数据结构,因为TreeMap内部是红黑树的数据结构,整体是有序的,而且还可以很快的搜索到大于某个元素的项及小于某个元素的项。 但是不清楚为什么,我代码提交后一直提示Memory Limit Exceeded。我在网上找了一份相似的代码,见代码2,就可以AC,有知道原因...
  • zdavb
  • zdavb
  • 2016-07-05 12:42
  • 648

[leetcode] 352. Data Stream as Disjoint Intervals 解题报告

题目链接: https://leetcode.com/problems/data-stream-as-disjoint-intervals/ Given a data stream input of non-negative integers a1, a2, ..., an, ......
  • qq508618087
  • qq508618087
  • 2016-06-01 07:24
  • 4655

leecode 解题总结:352. Data Stream as Disjoint Intervals

#include #include #include #include #include #include using namespace std; /* 问题: Given a data stream input of non-negative integers a1, a2, ......
  • qingyuanluofeng
  • qingyuanluofeng
  • 2017-03-02 11:15
  • 206

Data Stream as Disjoint Intervals

插入的新值有三种情况: 1、可以和右边合并 2、可以和左边合并 3、既不能和右边合并也不能和左边合并 class SummaryRanges { private: map m; public: /** Initialize your data structure here. */ ...
  • popvip44
  • popvip44
  • 2016-11-13 10:46
  • 82

【leetcode】Data Stream as Disjoint Intervals

题目链接:https://leetcode.com/problems/data-stream-as-disjoint-intervals/ Given a data stream input of non-negative integers a1, a2, ..., an, ..., summa...
  • yeqiuzs
  • yeqiuzs
  • 2016-06-01 21:47
  • 1361

Data Stream as Disjoint Intervals

第一次用TreeSet。。。 要懂得用这种结构 /** * Definition for an interval. * public class Interval { * int start; * int end; * Interval() { start = ...
  • sjphiChina
  • sjphiChina
  • 2016-09-02 23:21
  • 126

[Leetcode] 352. Data Stream as Disjoint Intervals 解题报告

题目: Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen so far as a list of disjoint intervals....
  • magicbean2
  • magicbean2
  • 2017-08-12 20:39
  • 109

352. Data Stream as Disjoint Intervals

Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen so far as a list of disjoint intervals. For exam...
  • wdlsjdl2
  • wdlsjdl2
  • 2016-07-14 22:40
  • 259

315. Data Stream as Disjoint Intervals

这题我自己没弄出来,参考了stellalai用户的代码。先翻译一下解法: 对于一个新的数n,我们寻找输入的一系列序号中包括这个数的指数,如果不存在就返回-1。这是依靠二分查找实现的。 找到Index后,我们有3种情况: ①、区间[index]已包含变量,直接输出即可。 ②、值可以被合并到区间...
  • vetala
  • vetala
  • 2017-04-12 21:41
  • 53
    个人资料
    • 访问:567991次
    • 积分:8667
    • 等级:
    • 排名:第2679名
    • 原创:305篇
    • 转载:6篇
    • 译文:0篇
    • 评论:37条
    博客专栏
    文章分类
    最新评论