编程之美之高效安排见面会
2014-08-14 19:06
176 查看
对于原题,书上写的很详细,即图的着色问题,这里主要看第一个扩展和leetcode上相关的问题
扩展问题一:
简单的说就是:有 N 个面试要同时进行, 他们的面试时间分别是 B[i], E[i]. 我们希望将这N个面试安排在若干地点, 不同的面试在同一时间不能再相同的面试点. 问至少需要多少个面试点
思路:先按照开始时间排序,对每个节点赋颜色值时,在它之前开始并且有时间重叠的区域的颜色不能使用
编程之美上说,如果只需要求出面试点的个数,则可以对所有开始结束时间进行排序,然后遍历,这里有一点没有说清楚,就是当结束时间和开始时间相同时,要把所有的结束时间放在前面,具体如下:
leetcode上两个和时间段相关的问题
Given a collection of intervals, merge all overlapping intervals.
For example,
Given
return
思路:这个题目比较简单,就是先按照开始时间排序,然后遍历整个数组,用两个指针指向相邻的两个位置,如果需要合并,就合并,不需要合并就得到一个结果。
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example 1:
Given intervals
as
Example 2:
Given
as
This is because the new interval
思路:把原链表分成三段,首尾是不需要进行合并的,中间是需要进行合并的,为了加快速度,可以用二分查找定位到第一个需要合并的节点的位置。
扩展问题一:
简单的说就是:有 N 个面试要同时进行, 他们的面试时间分别是 B[i], E[i]. 我们希望将这N个面试安排在若干地点, 不同的面试在同一时间不能再相同的面试点. 问至少需要多少个面试点
思路:先按照开始时间排序,对每个节点赋颜色值时,在它之前开始并且有时间重叠的区域的颜色不能使用
struct Interval { int start; int end; int color; Interval() : start(0), end(0),color(-1) {} Interval(int s, int e,int c) : start(s), end(e) ,color(c) {} }; bool operator<(const Interval& lhs,const Interval& rhs) { return (lhs.start < rhs.start || (lhs.start == rhs.start && lhs.end < rhs.end)); } bool isOverLap(const Interval& lhs,const Interval& rhs) { if(lhs.start >= rhs.start && lhs.start < rhs.end)return true; if(rhs.start >= lhs.start && rhs.start < lhs.end)return true; return false; } int interviewPoint(vector<Interval>& intervals) { sort(intervals.begin(),intervals.end());//按开始时间排序 int length = intervals.size(); vector<bool>isForbidden(length+1,false); int i,j,maxColor = 1; for(i = 0; i < length;++i) { for(j = 0;j < i;++j) { if(isOverLap(intervals[i],intervals[j]))isForbidden[intervals[j].color] = true;//如果区域重叠,则它的颜色不能使用 } for(j = 1;j <= maxColor;++j) { if(isForbidden[j] == false)break; } if(j > maxColor)intervals[i].color = ++maxColor; else intervals[i].color = j; isForbidden.assign(length+1,false); } return maxColor; }
编程之美上说,如果只需要求出面试点的个数,则可以对所有开始结束时间进行排序,然后遍历,这里有一点没有说清楚,就是当结束时间和开始时间相同时,要把所有的结束时间放在前面,具体如下:
struct Interval { int start; int end; Interval() : start(0), end(0) {} Interval(int s, int e,int c) : start(s), end(e){} }; struct Time //用于排序 { int time; bool isStart;//标记 Time(int t,bool s):time(t),isStart(s){} }; bool operator<(const Time& lhs,const Time& rhs) { return (lhs.time < rhs.time || lhs.time == rhs.time && !lhs.isStart); //时间相同时,结束时间在前 } int interviewPoint(vector<Interval>& intervals) { vector<Time> data; int i,maxColor = 0,count = 0; for(i = 0;i < intervals.size();++i) { data.push_back(Time(intervals[i].start,true)); data.push_back(Time(intervals[i].end,false)); } sort(data.begin(),data.end()); for(i = 0; i < data.size();++i) //遇到开始时间,加1,遇到结束时间,减1 { if(data[i].isStart) { if(++count > maxColor)maxColor = count; } else --count; } return maxColor; }
leetcode上两个和时间段相关的问题
Merge Intervals
Given a collection of intervals, merge all overlapping intervals.For example,
Given
[1,3],[2,6],[8,10],[15,18],
return
[1,6],[8,10],[15,18].
思路:这个题目比较简单,就是先按照开始时间排序,然后遍历整个数组,用两个指针指向相邻的两个位置,如果需要合并,就合并,不需要合并就得到一个结果。
struct Interval { int start; int end; Interval() : start(0), end(0) {} Interval(int s, int e) : start(s), end(e) {} }; bool operator<(const Interval& lhs,const Interval& rhs) { return (lhs.start < rhs.start || (lhs.start == rhs.start && lhs.end < rhs.end)); } class Solution { public: vector<Interval> merge(vector<Interval>& intervals) { sort(intervals.begin(),intervals.end());//按照开始时间排序 vector<Interval> res; vector<Interval>::iterator iter = intervals.begin(); Interval* cur = NULL; for(;iter != intervals.end();++iter)//进行时间段的合并 { if(cur != NULL) { if(cur -> end >= iter -> start) { cur -> end = (cur -> end > iter -> end) ? cur -> end : iter -> end;//这里改变了原来的数据,面试的时候要具体对待 } else { res.push_back(*cur); cur = &(*iter); } } else cur = &(*iter); } if(cur)res.push_back(*cur); return res; } };
Insert Interval
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).You may assume that the intervals were initially sorted according to their start times.
Example 1:
Given intervals
[1,3],[6,9], insert and merge
[2,5]in
as
[1,5],[6,9].
Example 2:
Given
[1,2],[3,5],[6,7],[8,10],[12,16], insert and merge
[4,9]in
as
[1,2],[3,10],[12,16].
This is because the new interval
[4,9]overlaps with
[3,5],[6,7],[8,10].
思路:把原链表分成三段,首尾是不需要进行合并的,中间是需要进行合并的,为了加快速度,可以用二分查找定位到第一个需要合并的节点的位置。
class Solution { public: int binarySearch(vector<Interval> &intervals,Interval newInterval)//定位到第一个需要合并的节点的位置 { int left = 0,right = intervals.size() - 1; while(left <= right) { int mid = left + ((right - left) >> 1); if(intervals[mid].end < newInterval.start)left = mid + 1; else right = mid - 1; } return left; } vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) { if(intervals.size() == 0)return vector<Interval>(1,newInterval); vector<Interval> res; int pos = binarySearch(intervals,newInterval); int i; for(i = 0; i < pos;++i)res.push_back(intervals[i]);//地一段 for(;i < intervals.size();++i)//第二段 { if(intervals[i].start >= newInterval.start && intervals[i].start <= newInterval.end || newInterval.start >= intervals[i].start && newInterval.start <= intervals[i].end) { newInterval.start = min(newInterval.start,intervals[i].start); newInterval.end = max(newInterval.end,intervals[i].end); } else break; } res.push_back(newInterval); for(;i < intervals.size();++i) res.push_back(intervals[i]);//第三段 return res; } };
相关文章推荐
- 编程之美-----高效率地安排见面会
- 高效安排见面会
- 编程之美--1.9高效率的安排见面会(解法二python)
- 编程之美----高效率地安排见面会----贪心策略
- 每日一题(20)——高效安排见面会
- 编程之美----高效率地安排见面会----贪心策略
- 【编程之美】高效率的安排见面会
- [编程之美]安排见面会
- 【编程之美】高效率的安排见面会
- 高效地安排见面会扩展问题
- 重新开始战斗07-编程之美-高效见面会
- 高效的安排见面会
- 每日一题(20)——高效安排见面会
- 读书笔记之编程之美 - 1.9 高效率地安排见面会
- 编程之美 set 15 高效率地安排见面会
- 高效率安排见面会问题(比编程之美的解法复杂度低n-1个数量级)
- 编程之美 - 安排见面会问题
- C#高效编程 读书笔记(1)
- .NET Socket服务编程之-高效连接接入编
- 我的iOS高效编程秘诀—坚持编程习惯