【LeetCode】406. Queue Reconstruction by Height

本文介绍了一种解决LeetCode上队列重构问题的算法。该算法首先根据k值将输入数据分组,然后按顺序插入各个组,最终实现队列的正确重构。文中详细解释了算法的实现过程,并提供了一份Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

问题链接:https://leetcode.com/problems/queue-reconstruction-by-height/#/description

Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue.

Note:

The number of people is less than 1,100.

Example

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

我的代码

思路探索

通过观察后发现,如果先按照k进行分组,就可以用插入法得到答案。

写代码的过程非常曲折,最后发现问题出在一个变量的作用域弄错了,应该写在循环之外。

通过的代码

public class Solution {

    private static class People {
        int h;
        int k;
        public People(int h,int k){
            this.h = h;
            this.k = k;
        }

        public int[] toArray(){
            int[] arr = new int[2];
            arr[0] = h;
            arr[1] = k;
            return arr;
        }
    }

    public int[][] reconstructQueue(int[][] people) {
        /*
        思路是这样的,首先根据k,把数据分成组,比如弄一个Map<Integer,List<People>>
        然后从k为0的List开始,依次插队。
        规则是这样的,拿到一个新元素开始,假设它的k=K。从list的最左边开始向右数,
        找到第K+1个比它大或者跟它相等的元素,如果到了list末尾也停止。记住下标,然后将元素插入进去。
        */

        int len = people.length;

        Map<Integer,ArrayList<People>> map = initMap(people);

        // 开始排序
        ArrayList<People> arr = new ArrayList<People>();
        int curK = 0;

        while(arr.size() != len || curK > 1000){
            // int a = 0;
            // if(a == 0){
            //     throw new RuntimeException("fdfdf");
            // }
            ArrayList<People> list = map.get(curK);
            curK++;
            if(list == null){

                continue;
            }
            for(People p : list){
                insertToRightPlace(arr,p);
            }
        }


        // 得到答案
        int[][] result = new int[len][2];
        for(int i = 0; i < len; i++){
            result[i] = arr.get(i).toArray();
        }

        return result;

    }

    private void insertToRightPlace(ArrayList<People> list, People p){
        int i = 0;
        int count = 0;
        for(; i < list.size(); i++){
            if(list.get(i).h >= p.h){
                count++;
            }
            if(count > p.k){ // 如果==的时候break了,会插入在这个元素的前面,导致不符合题意。
                break;
            }
        }

        list.add(i,p);


    }

    private Map<Integer,ArrayList<People>> initMap(int[][] people){
        int len = people.length;

        Map<Integer,ArrayList<People>> map = new HashMap<Integer,ArrayList<People>>();

        for(int i = 0; i < len; i++){
            int h = people[i][0];
            int k = people[i][1];
            ArrayList<People> list = map.get(k);
            if(list == null){
                list = new ArrayList<People>();
                map.put(k,list);
            }
            list = map.get(k);
            list.add(new People(h,k));
        }
        return map;
    }
}

打败了36.65的Java代码,也算不错了。好累啊。

讨论区

Easy concept with Python/C++/Java Solution

链接地址:https://discuss.leetcode.com/topic/60394/easy-concept-with-python-c-java-solution/2

嗯,在这个回答里学到了新的思路,不错不错。思路太长就不贴了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值