LintCode 821: Time Intersection (扫描线算法题)

  1. Time Intersection

Give two users’ ordered online time series, and each section records the user’s login time point x and offline time point y. Find out the time periods when both users are online at the same time, and output in ascending order.you need return a list of intervals.

Example
Example 1:

Input: seqA = [(1,2),(5,100)], seqB = [(1,6)]
Output: [(1,2),(5,6)]
Explanation: In these two time periods (1,2), (5,6), both users are online at the same time.
Example 2:

Input: seqA = [(1,2),(10,15)], seqB = [(3,5),(7,9)]
Output: []
Explanation: There is no time period, both users are online at the same time.
Notice
We guarantee that the length of online time series meet 1 <= len <= 1e6.
For a user’s online time series, any two of its sections do not intersect.

解法1:SweepLane算法
代码如下:

/**
 * Definition of Interval:
 * classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 * }
 */

struct Node {
    int eventTime;
    int eventFlag;
    Node(int et = -1, int ef = -1) : eventTime(et), eventFlag(ef) {}
    bool operator < (const Node & node) {
        if (this->eventTime == node.eventTime) {
            return this->eventFlag < node.eventFlag;
        }
        return this->eventTime < node.eventTime;
    }
};

class Solution {
public:
    /**
     * @param seqA: the list of intervals
     * @param seqB: the list of intervals
     * @return: the time periods
     */
    vector<Interval> timeIntersection(vector<Interval> &seqA, vector<Interval> &seqB) {
        int nA = seqA.size();
        if (nA == 0) return {};
        int nB = seqB.size();
        if (nB == 0) return {};

        vector<Node> nodes;
        for (auto s : seqA) {
            nodes.push_back(Node(s.start, 0));
            nodes.push_back(Node(s.end, 1));
        }
            
        for (auto s : seqB) {
            nodes.push_back(Node(s.start, 0)); 
            nodes.push_back(Node(s.end, 1));
        }
        
        sort(nodes.begin(), nodes.end());
        
        int n = nodes.size();
        vector<Interval> intervals;
        
        int count = 0;
        for (int i = 0; i < n; ++i) {
            if (nodes[i].eventFlag == 0) count++;
            else if (nodes[i].eventFlag == 1) count--;
            
            if (count == 2) {
                intervals.push_back(Interval(nodes[i].eventTime, nodes[i + 1].eventTime));
            }
        }
        
        return intervals;
    }
};

解法2: 直接来个loop。
注意:overlap的判定是 (a1 <= b2 && a2 >= b1) ,然后不管有没有overlap,每次把尾巴在前面的那个元素的list往后移动一个。

class Solution {
public:
    vector<vector<int>> intervalIntersection(vector<vector<int>>& firstList, vector<vector<int>>& secondList) {
        int n1 = firstList.size(), n2 = secondList.size();
        int pos1 = 0, pos2 = 0;
        vector<vector<int>> res;
        while (pos1 < n1 && pos2 < n2) {
            int a1 = firstList[pos1][0];
            int a2 = firstList[pos1][1];
            int b1 = secondList[pos2][0];
            int b2 = secondList[pos2][1];
            if (a1 <= b2 && a2 >= b1) { //overlap
                res.push_back({max(a1, b1), min(a2, b2)});
                
            }
            if (a2 >= b2) pos2++;
            else pos1++;
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值