题目链接:https://leetcode.com/problems/queue-reconstruction-by-height/?tab=Description
题意:给一个队列,每个人的身高以及他们前面的比他高的人的数量。求重构这个队列。
很简单,以前意淫过一道类似的题,不过是逆序数。这道题明显条件多了一点,不过不影响。
按照身高从小到大排序,然后在此基础上按照逆序数从大到小排序。用树状数组维护[1,pos]的总的空白位置数量,每次插入的时候从头到尾插,二分找到最左边的满足条件的位置后,更新空白数量-1即可。
甚至感觉像在写模拟。
1 class Solution { 2 public: 3 int n, bit[1100]; 4 int lowbit(int x) { 5 return x & (-x); 6 } 7 void update(int i, int x) { 8 while(i <= n) { 9 bit[i] += x; 10 i += lowbit(i); 11 } 12 } 13 int sum(int i) { 14 int ret = 0; 15 while(i) { 16 ret += bit[i]; 17 i -= lowbit(i); 18 } 19 return ret; 20 } 21 int lb(int val) { 22 int lo = 1, hi = n; 23 while(lo <= hi) { 24 int mid = (lo + hi) >> 1; 25 int x = sum(mid); 26 if(x >= val) hi = mid - 1; 27 else lo = mid + 1; 28 } 29 return lo; 30 } 31 static bool cmp(const pair<int, int>& a, const pair<int, int>& b) { 32 if(a.first != b.first) return a.first < b.first; 33 return a.second > b.second; 34 } 35 vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) { 36 pair<int, int> ret[1100]; 37 memset(bit, 0, sizeof(bit)); 38 n = people.size(); 39 for(int i = 2; i <= n; i++) update(i, 1); 40 sort(people.begin(), people.end(), cmp); 41 for(int i = 1; i <= n; i++) { 42 int pos = lb(people[i-1].second+1); 43 update(pos, -1); 44 ret[pos-1].first = people[i-1].first; 45 ret[pos-1].second = people[i-1].second; 46 } 47 people.clear(); 48 for(int i = 1; i <= n; i++) people.push_back(ret[i]); 49 return people; 50 } 51 };