1. 程式人生 > 其它 >【LeetCode】406. 根據身高重建佇列

【LeetCode】406. 根據身高重建佇列

406. 根據身高重建佇列

知識點:貪心

題目描述

假設有打亂順序的一群人站成一個佇列,陣列 people 表示佇列中一些人的屬性(不一定按順序)。每個 people[i] = [hi, ki] 表示第 i 個人的身高為 hi ,前面 正好 有 ki 個身高大於或等於 hi 的人。

請你重新構造並返回輸入陣列people 所表示的佇列。返回的佇列應該格式化為陣列 queue ,其中 queue[j] = [hj, kj] 是佇列中第 j 個人的屬性(queue[0] 是排在佇列前面的人)。

示例
輸入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
輸出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
解釋:
編號為 0 的人身高為 5 ,沒有身高更高或者相同的人排在他前面。
編號為 1 的人身高為 7 ,沒有身高更高或者相同的人排在他前面。
編號為 2 的人身高為 5 ,有 2 個身高更高或者相同的人排在他前面,即編號為 0 和 1 的人。
編號為 3 的人身高為 6 ,有 1 個身高更高或者相同的人排在他前面,即編號為 1 的人。
編號為 4 的人身高為 4 ,有 4 個身高更高或者相同的人排在他前面,即編號為 0、1、2、3 的人。
編號為 5 的人身高為 7 ,有 1 個身高更高或者相同的人排在他前面,即編號為 1 的人。
因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新構造後的佇列。

輸入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
輸出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]


解法一:貪心

在遇到這種數對,還涉及到排序的時候,往往會對第一個元素正向排序,第二個元素反向排序,或者反過來,能夠解決問題。也就是說,像這種有兩個維度的,一般情況下一定要去想先確定好一個,然後再確定另一個
所以我們可以選擇貪心策略:優先身高高的people,按照k來插入。

想一下為什麼這樣做:因為比他矮的人插入的話對他沒有影響。如果插在我後面,那肯定沒關係,如果插在我前面,那對我的k也沒影響,我的k只關心大於等於我的。

所以先按照身高降序排序,再按照k升序排列;為什麼k要升序呢,想一下同等身高的時候,k小的一定會在k大的前面,比如[5,3]和[5,2],如果我們先插入了3這個,那3被插在索引為3的位置上了,前面有3個大於等於自己的,那2再過來的時候,就只能插在3的前面,也就是索引2的位置,那這樣3前面就有4個大於等於自己的了。

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        Arrays.sort(people, new Comparator<int[]>(){
            public int compare(int[] o1, int[] o2){
                if(o2[0] != o1[0]){
                    return o2[0]-o1[0];  //按照身高降序;
                }else{
                    return o1[1]-o2[1]; //按k升序;
                }
            }
        });
        List<int[]> list = new ArrayList<>();
        for(int[] person : people){
            list.add(person[1], person);  //直接插到指定位置上就可以了;
        }
        return list.toArray(new int[list.size()][]);  //列表轉陣列;這個方法一定要會!
    }
}