Careercup - Google面试题 - 4699414551592960

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))。

代码:

  1 // http://www.careercup.com/question?id=4699414551592960

  2 #include <algorithm>

  3 #include <iostream>

  4 #include <string>

  5 #include <vector>

  6 using namespace std;

  7 

  8 struct Person {

  9     int height;

 10     int taller;

 11     string name;

 12     Person(int _height = 0, int _taller = 0, string _name = ""): 

 13         height(_height), taller(_taller), name(_name) {};

 14     bool operator < (const Person &other) {

 15         return this->height < other.height;

 16     };

 17     

 18     friend ostream& operator << (ostream &cout, const Person &p) {

 19         cout << '<'<< p.name << p.height << '>';

 20         return cout;

 21     };

 22 };

 23 

 24 template <class T>

 25 class BinaryIndexedTree {

 26 public:

 27     BinaryIndexedTree(int _n = 0): n(_n), v(_n + 1) {};

 28     

 29     int size() {

 30         return n;

 31     };

 32     

 33     void addAll(int x, const T &val) {

 34         while (x >= 1 && x <= n) {

 35             v[x] += val;

 36             x -= lowBit(x);

 37         }

 38     };

 39     

 40     void addInterval(int x, int y, const T &val) {

 41         addAll(x - 1, -val);

 42         addAll(y, val);

 43     };

 44     

 45     void clear() {

 46         v.resize(1);

 47         n = 0;

 48     };

 49     

 50     void resize(int new_n) {

 51         v.resize(new_n + 1);

 52         n = new_n;

 53     }

 54     

 55     T sum(int x) {

 56         T res = 0;

 57         while (x >= 1 && x <= n) {

 58             res += v[x];

 59             x += lowBit(x);

 60         }

 61         

 62         return res;

 63     };

 64     

 65     int lowerBound(const T &val) {

 66         int ll, mm, rr;

 67         

 68         if (n == 0) {

 69             return 0;

 70         }

 71 

 72         T res;

 73         if (val <= (res = sum(1))) {

 74             return 1;

 75         }

 76         if (val > (res = sum(n))) {

 77             return n + 1;

 78         }

 79         

 80         ll = 1;

 81         rr = n;

 82         while (rr - ll > 1) {

 83             mm = (ll + rr) / 2;

 84             res = sum(mm);

 85             if (val > res) {

 86                 ll = mm;

 87             } else {

 88                 rr = mm;

 89             }

 90         }

 91         

 92         return rr;

 93     }

 94 private:

 95     vector<T> v;

 96     int n;

 97     

 98     int lowBit(int x) {

 99         return x & -x;

100     };

101 };

102 

103 int main()

104 {

105     vector<Person> people;

106     vector<int> queue;

107     BinaryIndexedTree<int> bit;

108     int i, j;

109     int n;

110     

111     while (cin >> n && n > 0) {

112         people.resize(n);

113         for (i = 0; i < n; ++i) {

114             cin >> people[i].height >> people[i].taller >> people[i].name;

115         }

116         sort(people.begin(), people.end());

117         bit.resize(n);

118         queue.resize(n);

119         for (i = 1; i <= n; ++i) {

120             bit.addInterval(i, n, 1);

121         }

122         for (i = 1; i <= n; ++i) {

123             j = bit.lowerBound(people[i - 1].taller + 1);

124             queue[j - 1] = i;

125             bit.addInterval(j, n, -1);

126         }

127         for (i = 0; i < n; ++i) {

128             cout << people[queue[i] - 1];

129         }

130         cout << endl;

131         

132         people.clear();

133         queue.clear();

134         bit.clear();

135     }

136     

137     return 0;

138 }

 

你可能感兴趣的:(Google)