贪心策略---根据身高和序号重组队列

根据身高和序号重组队列

406. Queue Reconstruction by Height(Medium)

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]]

题目描述:

  一个学生用两个分量 (h, k) 描述,h 表示身高,k 表示排在前面的有 k 个学生的身高比他高或者和他一样高。

思路分析:

  换种思考方式,题目里面说了,每个位置的 k 的值,等于在这个位置之前 h 比它大的位置的数量。如果要向一个队列中插入一个人,要判断的就是插入的位置。那么如果可以确定,当前队列中的所有人的 h 值都比待插入的这个人的 h 值大,那么这个人的 k 值就是他应该插入的位置。并且可以确定,如果插入的是一个 h 值小于当前队列中所有人的 h 值的人,那么无论他的位置在哪,都不会影响当前队列中所有人的 k 值,即不会破坏当前队列的正确性。

  再看本题,我们只需要将这个队列按照 h 从高到低排序,然后依次插入到一个新的队列,这样就能保证新插入的人的 h 值始终小于(或等于)当前队列中所有人的 h 值,满足了上面的条件。

  再有一个问题,如果两个人的 h 值相同的时候该如何排序?如一个队列[[7,1],[7,0]],因为题目中已经指出了:每个人的 k 值,是在他的前面所有 h 值大于(或等于)他的 h 的人的个数,那么对于两个 h 值相同的人,他们的 k 值肯定是不同的,并且能够确定,k 值大的人应该排在后面。

代码:

public int[][]reconstructQueue(int[][]people){
    if(people==null||people.length==0)
        return null;
    Arrays.sort(people,new Comparator<int[]>(){
        @Override
        public int compare(int[]o1,int[]o2){
            return o1[0]==o2[0]?o1[1]-o2[1]:o2[0]-o1[0];
        }
    });
    List<int[]>res=new ArrayList<>();
    for(int[]q:people){
        res.add(q[1],q);
    }
    return res.toArray(people);
}
posted @ 2019-06-28 22:14  yjxyy  阅读(580)  评论(0编辑  收藏  举报