【LeetCode】406. Queue Reconstruction by Height 根据身高重建队列(Medium)(JAVA)

【LeetCode】406. Queue Reconstruction by Height 根据身高重建队列(Medium)(JAVA)

题目地址: https://leetcode.com/problems/queue-reconstruction-by-height/

题目描述:

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

题目大意

假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。

注意:
总人数少于1100人。

解题方法

  1. 先对数组排序,按照 people[i][0] 小的在前;如果相同,people[i][1] 小的在前
  2. 把数字按照要求插入 list 当中(计算前面大于当前元素的个数,直到多一个个数当于当前元素,就取当前位置插入)
class Solution {
    public int[][] reconstructQueue(int[][] people) {
        Arrays.sort(people, (a, b) -> (a[1] - b[1] == 0 ? a[0] - b[0] : a[1] - b[1]));
        List<int[]> res = new ArrayList<>();
        for (int i = 0; i < people.length; i++) {
            int index = -1;
            int count = people[i][1];
            for (int j = 0; j < res.size(); j++) {
                if (res.get(j)[0] >= people[i][0]) count--;
                if (count < 0) {
                    index = j;
                    break;
                }
            }
            res.add(index >= 0 ? index : res.size(), people[i]);
        }
        for (int i = 0; i < res.size(); i++) {
            people[i] = res.get(i);
        }
        return people;
    }
}

执行耗时:29 ms,击败了6.08% 的Java用户
内存消耗:39.3 MB,击败了92.29% 的Java用户

优化
  1. 还有更巧妙的方式,就是排序按照从后往前排的方式:按照 people[i][0] 大的在前;如果相同,people[i][1] 小的在前
  2. 因为大的都在前面了,所以后面插入的位置就是有多少个大于当前元素的,只要在 people[i][1] 插入 people[i] 元素即可
class Solution {
    public int[][] reconstructQueue(int[][] people) {
        Arrays.sort(people, (a, b) -> (a[0] - b[0] == 0 ? a[1] - b[1] : b[0] - a[0]));
        List<int[]> res = new ArrayList<>();
        for (int i = 0; i < people.length; i++) {
            res.add(people[i][1], people[i]);
        }
        for (int i = 0; i < res.size(); i++) {
            people[i] = res.get(i);
        }
        return people;
    }
}

执行耗时:7 ms,击败了99.62% 的Java用户
内存消耗:39.3 MB,击败了91.66% 的Java用户

欢迎关注我的公众号,LeetCode 每日一题更新
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值