LeetCode 352. 将数据流变为多个不相交区间(区间)

2024-04-15 22:48

本文主要是介绍LeetCode 352. 将数据流变为多个不相交区间(区间),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

给你一个由非负整数 a1, a2, …, an 组成的数据流输入,请你将到目前为止看到的数字总结为不相交的区间列表。

实现 SummaryRanges 类:

SummaryRanges() 使用一个空数据流初始化对象。
void addNum(int val) 向数据流中加入整数 val 。
int[][] getIntervals() 以不相交区间 [starti, endi] 的列表形式返回对数据流中整数的总结。

示例:

输入:
[“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]]

提示:

0 <= val <= 104
最多调用 addNum 和 getIntervals 方法 3 * 104 次

进阶:如果存在大量合并,并且与数据流的大小相比,不相交区间的数量很小,该怎么办?

思路:
一开始用的是list<pair<int,int>>lis来存,这样的话不能用二分,每次要通过遍历整个链表来维护区间关系。看了题解才发现,原来还可以用map来维护这个区间关系,太妙了。key表示左端点,value表示右端点。

将区间按照左端点排序(正好符合map排序规则)情况分为以下几种:

  1. val在最左边区间左边,可能是单独区间,也可能和最左区间合并
  2. val在某个区间之内
  3. val在两个区间之间,而且刚好挨着前一个区间右端点,可能出现左右区间合并的情况
  4. val在两个区间之间,而且刚好挨着后一个区间左端点,因为区间合并上面判过,这里无需再判
  5. val在两个区间之间,没有上述情况,所以作为一个单独区间

可以加一个[1e9,1e9]作为dummy区间,省去很多判断的麻烦

class SummaryRanges {
public:SummaryRanges() {mp[1e9] = 1e9;}void addNum(int val) {auto interval1 = mp.upper_bound(val);auto interval0 = (interval1 == mp.begin() ? mp.end() : prev(interval1));if(interval0 == mp.end()) {if(val == interval1 -> first - 1) {mp[val] = interval1 -> second;mp.erase(interval1);} else {mp[val] = val;}return;}if(val <= interval0 -> second && val >= interval0 -> first) {return;}if(val == interval0 -> second + 1) {interval0 -> second++;if(interval0 -> second == interval1 -> first - 1) {interval0 -> second = interval1 -> second;mp.erase(interval1);}} else if(val == interval1 -> first - 1) {mp[val] = interval1 -> second;mp.erase(interval1);} else {mp[val] = val;}}vector<vector<int>> getIntervals() {vector<vector<int>>ans;for(auto& it: mp) {if(it.first == 1e9) continue;ans.push_back({it.first, it.second});}return ans;}
private:map<int, int>mp;
};/*** Your SummaryRanges object will be instantiated and called as such:* SummaryRanges* obj = new SummaryRanges();* obj->addNum(val);* vector<vector<int>> param_2 = obj->getIntervals();*/

这篇关于LeetCode 352. 将数据流变为多个不相交区间(区间)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907145

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

poj 1127 线段相交的判定

题意: 有n根木棍,每根的端点坐标分别是 px, py, qx, qy。 判断每对木棍是否相连,当他们之间有公共点时,就认为他们相连。 并且通过相连的木棍相连的木棍也是相连的。 解析: 线段相交的判定。 首先,模板中的线段相交是不判端点的,所以要加一个端点在直线上的判定; 然后,端点在直线上的判定这个函数是不判定两个端点是同一个端点的情况的,所以要加是否端点相等的判断。 最后

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

hdu4267区间统计

题意:给一些数,有两种操作,一种是在[a,b] 区间内,对(i - a)% k == 0 的加value,另一种操作是询问某个位置的值。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import

hdu4417区间统计

给你一个数列{An},然后有m次查询,每次查询一段区间 [l,r] <= h 的值的个数。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamRead

hdu3333区间统计

题目大意:求一个区间内不重复数字的和,例如1 1 1 3,区间[1,4]的和为4。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &