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. Python之路【第八篇】:堡垒机实例以及数据库操作

    Python之路[第八篇]:堡垒机实例以及数据库操作   堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient ...

  2. 语音分享应用ios源码

    该源码是语音分享应用源码,本demo使用了科大讯飞语音识别作为分享内容的输入方式,同时也支持手动键盘输入分享内容,限制分享内容文字不能超过180个字符,分享内容输入完成后可以直接分享,分享SDK使用的 ...

  3. C++ 三种工厂模式

    工厂模式是将带有继承于基类的子类的创建过程交于一个工厂来创建,通过赋予不同的创建标识来创建不同的子类. 基于自己的理解和使用这里巩固一下工厂模式. 我们的项目目前使用最多的是简单工厂模式,不过其他两种 ...

  4. js事件 event.target

    我们购物车里,会时不时增加和删除产品时,就会绑定事件和解绑的动作. <ul> <li></li> <li></li> </ul> ...

  5. NetCat使用手册

    简介:   在网络工具中有“瑞士军刀”美誉的NetCat(以下简称nc),在我们用了N年了至今仍是爱不释手.因为它短小精悍(这个用在它身上很适合,现在有人已经将其修改成大约10K左右,而且功能不减少) ...

  6. 【原创】解决鼠标经过子元素触发mouseout,mouseover事件的问题

    关键词:父子元素关系  mouseout  mouseover  事件  事件冒泡 初期代码: <!DOCTYPE html> <html> <head> < ...

  7. Ksoap2 获取webservice返回值的getResponse() 出现的问题

    今天写了一个判断记录重复的webservcie 返回布尔类型 // 判断序列号在数据库是否重复 public static boolean isSerialNumExist(String serial ...

  8. 对于java反射的理解

    java中的反射是一种强大的工具,它能够创建灵活的代码,这些代码可以在运行时装配,无序在组件之间进行链接. 反射允许在编写与执行时,使程序代码能够接入装载到JVM的类的内部信息,而不是源代码中选定的类 ...

  9. python去掉空行

    #用strip(),split()两个方法都可以判断空行 infile=open('/.../','r') outfile=open('/.../','w') for li in infile.rea ...

  10. C 封装一个csv 解析库

    引言 最经关于基础C开发框架基本都搭建好了. 在研究githup,准备传上去. 可惜的是两会连githup 都登陆不进去. 三观很正的我也觉得, 这样不好. 双向标准, 共x党不是一个代表穷苦大众的党 ...