方法一
实现思路
规律 : 可以先从高度最小的开始安排顺序
例:输入为people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
一、 先将数组按照高度升序排序,当高度相同时按前面人数值升序排序)
处理后people = [[4,4],[5,0],[5,2],[6,1],[7,0],[7,1]]
二、 创建数组存储满足当前位置前面人数为i的下标值
如:book[2]=2 代表在数组2位置处,前面有两个元素大于当前值
所以初始化book[i]=i
三、 遍历people数组
四、 更新book数组
具体更新book细节,结合例子来看
[4,4]现在被放在了下标4的位置,开始更新book值
经排序之后先处理的高度值较小,后续的值一定大于现在放置的高度(也会存在等于的特殊情况后续单独考虑)
放置位置左侧book数值不会受影响,右侧位置的前面比我高的个数会减一(注意book[i]=j代表在下标j位置,比我高的个数有i个)
这种更新可以通过book[i]=book[i+1]实现
也就是book[4]=book[5]=5 ,在下标5比他高的个数有4个
更新book值
这里发现有些不同是由于,前面更新book值是考虑都大于当前值,但实际上个头相等也会被记为比我高,所以单独考虑,before=2,但由于之前有一个高位5的出现了,那么我只需要找before=1即可,在具体实现的时候需要有一个sum变量记录一下之前出现过多少个跟我一样高的,before=before - sum
之所以属于贪心的题目,应该是先处理最矮的,多个最矮的,先处理前面比它高最少的
实现代码
bool cmp(const vector<int> &a,const vector<int> &b){
if(a[0]!=b[0]) return a[0]<b[0];
else return a[1]<b[1];
}
class Solution {
public:
int find(vector<int>book,int v){
if(book[v]==v) return v;
else return find(book,book[v]);
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
int n=people.size();
if(n<2) return people;
vector<vector<int>> re(n);
vector<int>book(n,0);
int sum=0;
for(int i=0;i<n;i++){
book[i]=i;
}
sort(people.begin(),people.end(),cmp);
int b=people[0][0];
for(int i=0;i<n;i++){
int before=people[i][1];
if(i&&b==people[i][0]){
sum++;
before=before-sum;
}
else sum=0;
int index=book[before];
re[index]=people[i];
for(int i=before;i<n-1;i++){
book[i]=book[i+1];//find(book,book[i+1]);
}
b=people[i][0];
}
return re;
}
};
提交结果及分析
时间复杂度O(n)
方法二
实现思路
先放置高的位置,后续矮的人随意插入都不会影响高的结果
一、 将所有人按照身高降序排列,相同身高的情况按照K值升序排列
二、 遍历数组进行插入
people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
排序之后为[[7,0],[7,1],[6,1],[5,0],[5,2],[4,4]]
按照此思想一次插入:
[[7,0]]
[[7,0],[7,1]]
[[7,0],[6,1],[7,1]]
[[5,0],[7,0],[6,1],[7,1]]
[[5,0],[7,0],[5,2],[6,1],[7,1]]
[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
实现代码
bool cmp(const vector<int> &a,const vector<int> &b){
return a[0]>b[0]||a[0]==b[0]&&a[1]<b[1];
}
class Solution {
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
int n=people.size();
if(n<2) return people;
vector<vector<int>> res;
sort(people.begin(),people.end(),cmp);
for(auto p:people) res.insert(res.begin()+p[1],p);
return res;
}
};
提交结果及分析
时间复杂度O(n)