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;
}
}