Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k)
, where h
is the height of the person and k
is the number of people in front of this person who have a height greater than or equal to h
. Write an algorithm to reconstruct the queue.
Note:
The number of people is less than 1,100.
Example
Input: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] Output: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
这一题总的来说个人觉得还是很有难度的。
思路:最开始很容易想到,随便选一种对整个数列进行排序, 先按k从小到大排,相同的k按照h从小到大排。
方法一,我的思路就是,对每一个People,排在他前面的人比他个字高的人的个数(排序完成以后,第一个人的位置肯定是对的的,因为假如第一个不对的话,不可能有人比他高, 但是个数又比他少的了,这里用反证法可以得出)。如果数到他的时候,刚刚好,那么他的位置就不需要改变;如果还没到他的时候,个数就已经够了,那么就再往下数一个比他高的,把他插入到这个人前面就可以了。例如:
排序好以后的数列是:50,70,61,71,52,44
- 检查50,不变
- 检查70,不变
- 检查61,有1个70符合,不变。
- 检查71,有1个70符合,不变。
- 检查52,50符合,70符合,61符合,61已经是第3个了,所以把52插入到61前面,当前序列是50,70,52,61,71,44。(这个地方需要注意的是,将52插入到61前面,并不影响61的相对位置,因为只会把一个矮的插到高的前面,对高的没有影响,不会把高的插到矮的前面)
LinkedList<People> listPeople = new LinkedList<People>();
public int[][] reconstructQueue(int[][] people) {
for (int[] is : people) {
listPeople.add(new People(is[0], is[1]));
}
Collections.sort(listPeople);
for (int i = 0; i < listPeople.size(); i++) {
int nBigger = 0;
People pCurrent = listPeople.get(i);
for (int j = 0; j < i; j++) {
if (listPeople.get(j).nH >= pCurrent.nH) {
nBigger++;
}
if (nBigger > pCurrent.nK) {
listPeople.remove(i);
listPeople.add(j, pCurrent);
break;
}
}
}
for (int i = 0; i < people.length; i++) {
people[i][0]=listPeople.get(i).nH;
people[i][1]=listPeople.get(i).nK;
}
return people;
}
public class Solution {
List<int[]> listPeople = new LinkedList<int[]>();
public int[][] reconstructQueue(int[][] people) {
for (int[] p : people) {
listPeople.add(new int[] { p[0], p[1], p[1] });
}
int[][] nArrAns = new int[people.length][];
int nIndex = 0;
while (listPeople.size() > 0) {
Collections.sort(listPeople, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
if (a[1] == b[1]) {
return a[0] - b[0];
}
return a[1] - b[1];
}
});
nArrAns[nIndex] = new int[] { listPeople.get(0)[0], listPeople.get(0)[2] };
listPeople.remove(0);
for (int[] nCurPeople : listPeople) {
if (nCurPeople[0] <= nArrAns[nIndex][0]) {
nCurPeople[1] -= 1;
}
}
nIndex++;
}
return nArrAns;
}
}