您的位置:首页 > 职场人生

Careercup - Google面试题 - 4699414551592960

2014-05-06 13:59 330 查看
2014-05-06 13:34

题目链接

原题:

we have a random list of people. each person knows his own height and the number of tall people in front of him. write a code to make the equivalent queue.
for example :
input: <"Height","NumberOfTall","Name">,
<6,2,"A">,<1,4,"B">,<11,0,"C">,<5,1,"D">,<10,0,"E">,<4,0,"F">
output: "F","E","D","C","B","A" --> end of queue


题目:有一队人正在排队,告诉你每个人的姓名、身高(目前默认都不相同),以及他/她所看到的前面比他高的人。请你计算出这个队伍里各个人的顺序。

解法:从最矮的人入手。对于最矮的人,他所看到的所有人都比他高,所以如果他看到有K个人比他高,那么他一定排在K + 1名。我的代码是当时琢磨了很久,采用树状数组写出来的。此处的树状数组提供快速修改区间、查询单个元素的能力,能做到对数时间。现在居然已经忘了当时的具体思路。总体思想是先按身高升序排序,然后逐个确定每个人在队列里的位置。关键的一点:每次都只能确定当前最矮的人排在哪儿。树状数组中维护的值c[i]的意义,是记录当前位置的前面有多少个比它高。其中还有个方法用到二分搜索,所以整体复杂度是比较奇怪的O(n * log(n) + n * log^2(n)) = O(n * log^2(n))。

代码:

// http://www.careercup.com/question?id=4699414551592960 #include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Person {
int height;
int taller;
string name;
Person(int _height = 0, int _taller = 0, string _name = ""):
height(_height), taller(_taller), name(_name) {};
bool operator < (const Person &other) {
return this->height < other.height;
};

friend ostream& operator << (ostream &cout, const Person &p) {
cout << '<'<< p.name << p.height << '>';
return cout;
};
};

template <class T>
class BinaryIndexedTree {
public:
BinaryIndexedTree(int _n = 0): n(_n), v(_n + 1) {};

int size() {
return n;
};

void addAll(int x, const T &val) {
while (x >= 1 && x <= n) {
v[x] += val;
x -= lowBit(x);
}
};

void addInterval(int x, int y, const T &val) {
addAll(x - 1, -val);
addAll(y, val);
};

void clear() {
v.resize(1);
n = 0;
};

void resize(int new_n) {
v.resize(new_n + 1);
n = new_n;
}

T sum(int x) {
T res = 0;
while (x >= 1 && x <= n) {
res += v[x];
x += lowBit(x);
}

return res;
};

int lowerBound(const T &val) {
int ll, mm, rr;

if (n == 0) {
return 0;
}

T res;
if (val <= (res = sum(1))) {
return 1;
}
if (val > (res = sum(n))) {
return n + 1;
}

ll = 1;
rr = n;
while (rr - ll > 1) {
mm = (ll + rr) / 2;
res = sum(mm);
if (val > res) {
ll = mm;
} else {
rr = mm;
}
}

return rr;
}
private:
vector<T> v;
int n;

int lowBit(int x) {
return x & -x;
};
};

int main()
{
vector<Person> people;
vector<int> queue;
BinaryIndexedTree<int> bit;
int i, j;
int n;

while (cin >> n && n > 0) {
people.resize(n);
for (i = 0; i < n; ++i) {
cin >> people[i].height >> people[i].taller >> people[i].name;
}
sort(people.begin(), people.end());
bit.resize(n);
queue.resize(n);
for (i = 1; i <= n; ++i) {
bit.addInterval(i, n, 1);
}
for (i = 1; i <= n; ++i) {
j = bit.lowerBound(people[i - 1].taller + 1);
queue[j - 1] = i;
bit.addInterval(j, n, -1);
}
for (i = 0; i < n; ++i) {
cout << people[queue[i] - 1];
}
cout << endl;

people.clear();
queue.clear();
bit.clear();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: