假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)
表示,其中h
是这个人的身高,k
是排在这个人前面且身高大于或等于h
的人数。 编写一个算法来重建这个队列。
思想:贪心算法。
先把这些人按高-->矮排列,因为高个子在前面,矮个子插入的时候,不会对高个子产生影响。比如前面是【7,0】要插入【5,0】,把【5,0】放在最前面对【7,0】没有影响。而如果反过来【7,0】插入【5,0】就会产生影响使应该为【5,1】。
排列的时候,身高一样的人按照K由小到大排列,这个道理很简单。
最后,把这些人按已经排好的顺序插入到自己K的位置上去,如果该位置已经有元素,就让该元素后与后面的元素后移一位。因为我们插入的是比已经插入的元素矮的元素,且K值也是同等身高里面矮的那个,所以后移不会对已经插入的造成影响。
然后考虑方法,两次排序可以使用java里面ArraysSort,https://blog.csdn.net/tt_twilight/article/details/70859804这是我发现的比较好的讲解。
要实现后面的插入,可以考虑List的add方法:
List.add(int index, E element)
在指定位置中插入元素,如果该位置有元素,则把该元素以及后面的所有元素后移
最后返回类型是二维数组,用到Quene.toArray();
public int[][] reconstructQueue(int[][] people) {
if(people.length == 0 || people == null || people[0].length == 0) return people;
//先给身高排序,
Arrays.sort(people, (a,b)->(a[0]==b[0] ? a[1]-b[1]:b[0]-a[0]));//比较,最高的在前面,若一样高,则排序小的在前面
List<int[]> res = new ArrayList<>(people.length);
for(int[] p:people)
{
res.add(p[1], p);
}
return res.toArray(new int[res.size()][]);
}