Careercup - Google面试题 - 6332750214725632
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的更多相关文章
- Careercup - Google面试题 - 5732809947742208
2014-05-03 22:10 题目链接 原题: Given a dictionary, and a list of letters ( or consider as a string), find ...
- Careercup - Google面试题 - 5085331422445568
2014-05-08 23:45 题目链接 原题: How would you use Dijkstra's algorithm to solve travel salesman problem, w ...
- Careercup - Google面试题 - 4847954317803520
2014-05-08 21:33 题目链接 原题: largest number that an int variable can fit given a memory of certain size ...
- Careercup - Google面试题 - 5634470967246848
2014-05-06 07:11 题目链接 原题: Find a shortest path ,) to (N,N), assume is destination, use memorization ...
- Careercup - Google面试题 - 5680330589601792
2014-05-08 23:18 题目链接 原题: If you have data coming in rapid succession what is the best way of dealin ...
- Careercup - Google面试题 - 5424071030341632
2014-05-08 22:55 题目链接 原题: Given a list of strings. Produce a list of the longest common suffixes. If ...
- Careercup - Google面试题 - 5377673471721472
2014-05-08 22:42 题目链接 原题: How would you split a search query across multiple machines? 题目:如何把一个搜索que ...
- Careercup - Google面试题 - 6331648220069888
2014-05-08 22:27 题目链接 原题: What's the tracking algorithm of nearest location to some friends that are ...
- Careercup - Google面试题 - 5692127791022080
2014-05-08 22:09 题目链接 原题: Implement a class to create timer object in OOP 题目:用OOP思想设计一个计时器类. 解法:我根据自 ...
随机推荐
- 隐藏DLL
先来推广一下QQ群:61618925.欢迎各位爱好编程的加入. 在外挂或者病毒中,经常需要隐藏掉自己注入的DLL,以免被发现.下面就是一个隐藏DLL的通用模块,用的时候只需要加入到相关模块中即可. 详 ...
- RocketMQ学习记录
RocketMQ是一款分布式.队列模型的消息中间件,具有以下特点: 1.能够保证严格的消息顺序 2.提供丰富的消息拉取模式 3.高效的订阅者水平扩展能力 4.实时的消息订阅机制 5.亿级消息堆积能力 ...
- js中forEach无法跳出循环?
1. forEach() forEach() 方法从头至尾遍历数组,为每个元素调用指定的函数.如上所述,传递的函数作为forEach()的第一个参数.然后forEach()使用三个参数调用该 函数:数 ...
- C++求等比数列之和
题目内容:已知q与n,求等比数列之和:1+q+q2+q3+q4+……+qn. 输入描述:输入数据不多于50对,每对数据含有一个整数n(1<=n<=20).一个小数q(0<q<2 ...
- Mac上添加adb_usb.ini
max上添加android驱动支持 用到的命令: 命令方式最简单,键入如下两行命令你就可以实现对文件的现实和隐藏功能了.这个时候肯定会有童鞋问:“在哪里敲命令呢?”,Launchpad——其他——终端 ...
- 多分类问题multicalss classification
多分类问题:有N个类别C1,C2,...,Cn,多分类学习的基本思路是"拆解法",即将多分类任务拆分为若干个而分类任务求解,最经典的拆分策略是:"一对一",&q ...
- jquery.unobtrusive-ajax.js源码阅读
/*! ** Unobtrusive Ajax support library for jQuery ** Copyright (C) Microsoft Corporation. All right ...
- hashCode()和toString()
hashCode函数和toString函数也在Object类中,同样,所有的类都继承了这2个函数. hashCode函数用于生成哈希码,没有参数,返回值为整型 把u的值作为键存入map中,使用get方 ...
- 菜鸟学习Hibernate——持久层框架
一.Java操作数据库的阶段. Java对数据库进行操作经历了三个阶段. 1.1操作JDBC阶段 这个阶段就是利用JDBC类来操作数据库.这个阶段出现了两个问题: 代码过度重复:在每一次数据库操作的是 ...
- SharePoint 项目的死法(一)
SharePoint是Microsoft的一个巨NB的产品, 从可查到的数据来看, 财富500强中已经有超过80%的企业已经使用了SharePoint的不同版本,从项目实施的经验来看, 个人感觉这个数 ...