力扣406-根据身高重建队列——贪心算法

题目描述

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

解题思路

拿到这道题没什么思路,看了大佬的题解才顿悟!

这道题主要是将原来的数组排序,首先按照第一个维度降序排列,然后第二个维度升序排列。

[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]经过排列之后变成 [5,0],[7,0],5,2],[6,1],[4,4],[7,1]

在这个排序问题上我纠结了很久,前几道题目就遇见过,主要是针对数组的自定义排序,需要实现Comparator接口的compare方法。具体实现为

Arrays.sort(people,new Comparator(){
            @Override
            public int compare(int[] people1,int[] people2){
                if(people1[0] != people2[0]){
                    //第一个元素不相等时,按照第一个元素降序排列
                    return people2[0]-people1[0];
                }else{
                    //第一个元素相等时,按照第二个元素升序排列
                    return people1[1]-people2[1];
                }
            }
        });

排序完成之后,需要首先建立一个动态list来存储排序完成之后的元素。

这里通过遍历people,比较 people [i][1] 与 list.size() 的大小,如果 people [i][1] < list.size() ,则要把people [i] insert 进 list 的第 i 位置,反之,则直接追加到 list 的后面。

这里可以认为 如果一个人身高比他高的人数比队里已经排好队的人还多或者相等,那他就应该站在后面;如果身高比他高的人数小于队里已经排好队的人数,那他应该插在队里面的某个位置,这个位置就是第 i 位。

下面是一个例子:

力扣406-根据身高重建队列——贪心算法_第1张图片

 

力扣406-根据身高重建队列——贪心算法_第2张图片

 

力扣406-根据身高重建队列——贪心算法_第3张图片

 

力扣406-根据身高重建队列——贪心算法_第4张图片

 

力扣406-根据身高重建队列——贪心算法_第5张图片

 

力扣406-根据身高重建队列——贪心算法_第6张图片

 

力扣406-根据身高重建队列——贪心算法_第7张图片

 在创建 list 的时候,ArrayList 或者LinkList 都可以,但是涉及到 add 或 insert 比较多的选择 LinkList会比较好,最后记得将 List 转换为数组。

输入输出示例

力扣406-根据身高重建队列——贪心算法_第8张图片

代码

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        //按数组第一个元素降序,第二个元素升序排序
        Arrays.sort(people,new Comparator(){
            @Override
            public int compare(int[] people1,int[] people2){
                if(people1[0] != people2[0]){
                    //第一个元素不相等时,按照第一个元素降序排列
                    return people2[0]-people1[0];
                }else{
                    //第一个元素相等时,按照第二个元素升序排列
                    return people1[1]-people2[1];
                }
            }
        });
        //新建一个arr,用于保存结果
        ArrayList arr = new ArrayList<>();
        for(int i = 0; i < people.length; i++){
            if(arr.size() > people[i][1]){
                //如果arr中元素个数大于第i人前面应有人数时,应该把people[i]插入people[i][1]的位置
                arr.add(people[i][1],people[i]);
            }else{
                //如果arr中元素个数小于或等于第i人前面应有人数时,应该把people[i]插入arr尾部
                arr.add(arr.size(),people[i]);
            }
        }
        //将arr转化为数组
        return arr.toArray(new int[arr.size()][]);
    }
}

你可能感兴趣的:(从暴力搜索开始!,贪心算法,leetcode,算法)