2014-05-06 10:18

题目链接

原题:

Given a set of intervals, find the interval which has the maximum number of intersections (not the length of a particular intersection). So if input (,) (,) (,), (,) should be returned. Some suggest to use Interval Tree to get this done in O(logn), but I did not understand how to construct and use the Interval Tree after reading its wiki page. Is there any other way to do it? If Interval tree is the only option, please educate me how to construct/use one. Thanks.

题目:有一堆一维的区间,请判断其中和其他区间相交次数最多的区间是哪一个。比如例子(1, 6)、(2, 3)、(4, 11),(1, 6)和其他两个相交了,所以是相交最多的。另外,这位叫“Guy”的老兄又在秀自己的无知了。说自己的第一想法是用线段树来解题,然后又说自己看了Wiki以后不知道怎么写线段树(既然压根儿不会你提它干嘛)。

解法:我的第一想法是可以用线段树,不过我不会写线段树,所以我试着用树状数组来解决问题。没想到,还真琢磨出一个来。一种暴力的解法自然是两层循环遍历,统计谁的相交次数最多。如果想把复杂度降低到O(n * log(n)),就得使元素有序。首先要明白一点:当A区间和B区间相交时,A和B的相交次数都要加1。那么,当A和BCD都相交时,A的相交次数直接加3,B、C、D的相交次数都加1。如果直接就这么加,复杂度肯定是平方级别的。但你既然看到“都加1”这种字眼,应该会联想到树状数组。树状数组的一种适用模型,就是给区间加上同一个值,然后查询单个元素,符合这道题的需求。我的代码里实现了一个简单的树状数组类,可以批量修改元素,和查询单个元素。单个操作的时间都是O(log(n))。这样n个区间统计完了以后,可以做到O(n * log(n))。在做相交统计之前,需要保证元素有序,比如按"先X后Y"或者“先Y后X”的顺序给区间排序,这个过程也是O(n * log(n))的。总体时间复杂度为O(n * log(n))。从这题可以看出:出题人不靠谱,下面回帖的答题者也大多不靠谱,有光说思路不写代码的,有分析完全错误的,还有断言时间复杂度不可能低于O(n^2)的。总之,这一题让我对Careercup上的题目质量大失所望。如果像“Guy”这样水平的用户活跃在Careercup上,这网站就完蛋了。如果需要了解树状数组,可以自行百度“树状数组”或者Google“Binary Indexed Tree”。

代码:

 // http://www.careercup.com/question?id=6332750214725632
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std; class BinaryIndexedTree {
public:
BinaryIndexedTree(int _n = ): n(_n) {
v.resize(n + );
}; // add val to all elements from v[1] to v[x]
void addAll(int x, int val) {
while (x >= ) {
v[x] += val;
x -= lowBit(x);
}
}; // add val to all elements from v[x] to v[y]
void addInterval(int x, int y, int val) {
if (x > y) {
addInterval(y, x, val);
return;
}
addAll(x - , -val);
addAll(y, val);
}; // return v[x]
int sum(int x) {
int res = ;
while (x <= n) {
res += v[x];
x += lowBit(x);
} return res;
}; ~BinaryIndexedTree() {
v.clear();
};
private:
int n;
vector<int> v; int lowBit(int x) {
return x & -x;
};
}; struct Interval {
int start;
int end;
Interval(int _start = , int _end = ): start(_start), end(_end) {}; bool operator < (const Interval &other) {
if (start != other.start) {
return start < other.start;
} else {
return end < other.end;
}
}; friend ostream& operator << (ostream &cout, const Interval &i) {
cout << '(' << i.start << ',' << i.end << ')';
return cout;
};
}; Interval solve(vector<Interval> &v)
{
int n = (int)v.size(); if (n == ) {
return Interval(, );
} else if (n == ) {
return v[];
} sort(v.begin(), v.end());
BinaryIndexedTree bit(n); int i, j;
int ll, rr, mm;
for (i = ; i < n - ; ++i) {
if (v[i + ].start >= v[i].end) {
// no overlapping
continue;
} if (v[n - ].start < v[i].end) {
// all overlapped
j = n - ;
} else {
ll = i + ;
rr = n - ;
while (rr - ll > ) {
mm = (ll + rr) / ;
if (v[mm].start < v[i].end) {
ll = mm;
} else {
rr = mm;
}
}
j = ll;
}
// from [i + 1, j], they all overlap with v[i].
bit.addInterval(i + , j + , );
bit.addInterval(i + , i + , j - i);
} int ri;
int res, mres; ri = ;
mres = bit.sum();
for (i = ; i < n; ++i) {
res = bit.sum(i + );
ri = res > mres ? i : ri;
} return v[ri];
} int main()
{
int i;
int n;
vector<Interval> v;
Interval res; while (cin >> n && n > ) {
v.resize(n);
for (i = ; i < n; ++i) {
cin >> v[i].start >> v[i].end;
}
res = solve(v);
cout << res << endl;
v.clear();
} return ;
} /*
// A simple test for the BIT above.
int main()
{
string cmd;
int n;
BinaryIndexedTree *bit = nullptr;
int x, y, val;
int i; while (cin >> n && n > 0) {
bit = new BinaryIndexedTree(n);
while (true) {
for (i = 1; i <= n; ++i) {
cout << bit->sum(i) << ' ';
}
cout << endl;
cin >> cmd;
if (cmd == "e") {
break;
} else if (cmd == "a") {
cin >> x >> val;
bit->addAll(x, val);
} else if (cmd == "ai") {
cin >> x >> y >> val;
bit->addInterval(x, y, val);
}
}
delete bit;
bit = nullptr;
} return 0;
}
*/

Careercup - Google面试题 - 6332750214725632的更多相关文章

  1. Careercup - Google面试题 - 5732809947742208

    2014-05-03 22:10 题目链接 原题: Given a dictionary, and a list of letters ( or consider as a string), find ...

  2. Careercup - Google面试题 - 5085331422445568

    2014-05-08 23:45 题目链接 原题: How would you use Dijkstra's algorithm to solve travel salesman problem, w ...

  3. Careercup - Google面试题 - 4847954317803520

    2014-05-08 21:33 题目链接 原题: largest number that an int variable can fit given a memory of certain size ...

  4. Careercup - Google面试题 - 5634470967246848

    2014-05-06 07:11 题目链接 原题: Find a shortest path ,) to (N,N), assume is destination, use memorization ...

  5. Careercup - Google面试题 - 5680330589601792

    2014-05-08 23:18 题目链接 原题: If you have data coming in rapid succession what is the best way of dealin ...

  6. Careercup - Google面试题 - 5424071030341632

    2014-05-08 22:55 题目链接 原题: Given a list of strings. Produce a list of the longest common suffixes. If ...

  7. Careercup - Google面试题 - 5377673471721472

    2014-05-08 22:42 题目链接 原题: How would you split a search query across multiple machines? 题目:如何把一个搜索que ...

  8. Careercup - Google面试题 - 6331648220069888

    2014-05-08 22:27 题目链接 原题: What's the tracking algorithm of nearest location to some friends that are ...

  9. Careercup - Google面试题 - 5692127791022080

    2014-05-08 22:09 题目链接 原题: Implement a class to create timer object in OOP 题目:用OOP思想设计一个计时器类. 解法:我根据自 ...

随机推荐

  1. banner淡出效果

    <div class="banner"> <div class="ban"></div> <ul class=&quo ...

  2. 自动计算尺寸列表功能案例ios源码

    源码HTKDynamicResizingCell,HTKDynamicResizingCell提供自动计算尺寸的TableViewCell/CollectionViewCel,只要设置了合适AutoL ...

  3. linux安装ftp服务器

    Ftp(文件传输协议) 概念 FTP是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”.用于Internet上的控制文件的双向传输.同时,它也是一个应用 ...

  4. SubsetsTotal Accepted:49746Total Submissions:176257My Submissions

    Subsets Total Accepted: 49746 Total Submissions: 176257My Submissions Given a set of distinct intege ...

  5. css3内处理

    1.插入文字:content属性:          p:after{content:"内容"}          p:before{content:"内容"} ...

  6. C#解析JSON字符串总结

    JSON文件读取到内存中就是字符串,.NET操作JSON就是生成与解析JSON字符串. 操作JSON通常有以下几种方式: 1. 原始方式:按照JSON字符串自己来解析. 2. 通用方式[★★★★★]: ...

  7. C#获取本周周一的日期

    /// <summary> /// 获取本周的周一日期 /// </summary> /// <returns></returns> public st ...

  8. Lua 多维表的遍历中的赋值

    说到Lua的遍历将要使用到循环:先说遍历再说循环: 遇到这样类似结构的一个table Data={ []={p1=,pa={,,}}, []={p1=,pa={,,}}, []={p1=,pa={,, ...

  9. onActivityResult无法调用

    最新项目中使用到了Fragment.在fragment中重载了onActivityResult方法,始终无法调用到. 大体是这样:选择图片的功能纠结了很久,能正常发送选择图片,但是选择后无法调用到on ...

  10. emlog模板制作帮助手册

    emlog基本模板文件 必须文件: main.css: CSS(样式表)文件 log_list.php: 日志列表页模板 echo_log.php: 日志页模板 page.php: 页面(page)模 ...