题目大意:
假设有一队人随机站成一个圈。每个人通过一对整数(h, k)描述,其中h是其身高,k是站在他前面并且身高不低于他的人数。编写算法重构队列
我的算法Java:
public class Solution {
public int[][] reconstructQueue(int[][] people) {
int size = people.length;
int[][] newArray = new int[size][2];
int i = 0, j = 0;
int tempk = 0;
int temph = 0;
// 冒泡排序过程
// 排序的依据是什么呢?
// 首先:按照第一个位置的大小从大到小排列,保证后面的插入不会影响到前面已经插入的值(因为后
// 面的比较大的话,之前插入的小值的h可能就会变成不满足状态)
// 其次:如果大小相当的情况,那么比较第二位,按照从小到大的情况排列,以保证不会被影响
for(i=0; i<size; i++){
for(j=0; j<size-1-i;j++){
if(people[j][0] < people[j+1][0] || (people[j][0] == people[j+1][0] && people[j][1] > people[j+1][1])){
tempk = people[j][1];
temph = people[j][0];
people[j][1] = people[j+1][1];
people[j][0] = people[j+1][0];
people[j+1][1] = tempk;
people[j+1][0] = temph;
}
}
}
// 插入过程
for(i=0;i<size;i++){
int curH = people[i][0]; // 获取当前的h
int curK = people[i][1]; // 获取当前的k
// 前往后遍历每一个位置,如果合适则插入
int count = 0; // count代表当前位置之前(包括当前状态)比我们要插入结点大或等于的数量
for(j=0; j<=i; j++){
if(count == curK){ // 如果合适则用j记录此位置
break;
}
if(curH <= newArray[j][0]){
count++;
}
}
// 把j后面的从后往前循环后移
for(int x=i;x>j;x--){ // 把j+1的之后的都往后移动一个
newArray[x][0] = newArray[x-1][0];
newArray[x][1] = newArray[x-1][1];
}
// 插入
newArray[j][0] = curH;
newArray[j][1] = curK;
}
return newArray;
}
}
大神代码
public class Solution {
public int[][] reconstructQueue(int[][] people) {
int size = people.length;
// 使用集合的形式,可以更方便的进行排序
LinkedList<int[]> list = new LinkedList<int[]>();
for (int i = 0; i < size; i++) {
list.add(new int[]{people[i][0], people[i][1], 0});
}
int ans[][] = new int[size][];
for (int i = 0; i < size; i++) {
// 排序使用Colleactions类来实现
Collections.sort(list, 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];
}
});
int[] head = list.removeFirst();
ans[i] = new int[]{head[0], head[1] + head[2]};
for (int[] p : list) {
if (p[0] <= head[0]) {
p[1] -= 1;
p[2] += 1;
}
}
}
return ans;
}
}