java数据结构与算法刷题-----LeetCode406. 根据身高重建队列

文章讲述了如何使用Java实现一个从高到底排序的解决方案,利用快速排序对身高进行降序排列,再通过插入排序处理相同身高的人,确保满足特定条件。涉及到的时间复杂度和空间复杂度分析也包含在内。

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

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.youkuaiyun.com/grd_java/article/details/123063846

文章目录

在这里插入图片描述

1. 从高到底排序

解题思路:时间复杂度O( n 2 n^2 n2),首先按照身高降序进行快速排序需要 n ∗ l o g 2 n n*log_{2} n nlog2n,之后需要按照前面有几个人比它高,进行插入排序,需要O( n 2 n^2 n2),时间复杂度按大头来,所以是O( n 2 n^2 n2)。空间复杂度O( l o g 2 n log_{2} n log2n),快速排序的栈空间
  1. 先将整个数组按照第一个字段(身高)进行降序排列。

如果遇到身高一样的,按照第二个字段进行升序排列。简单来说,身高一样的哥几个,谁的第二个字段值小,谁排前面。

  1. 然后使用插入算法,依次将每个元素按照第二个字段插入到对应位置(第二个字段是几就插入到第几个位置)
  1. 因为数组此时完成了按照身高降序排列,单拿出任何一个人来说,它现在前面的人,都比它高。
  2. 如果当前这个人,需要2个比它高或者和它一样高的人排它前面,那他就放到第2个位置。
  3. 因为它前面都比它高,假设它前面有5个人,那么就有5个比它高的。此时将其插入到第二个位置,就只有0和1这两个位置的人比它高了。
  1. 因为是按照第一个字段降序排列,第二个字段代表前面比它高或者和它一样高的人数。所以后面的元素(都比前面的小)插入到前面来,对于这些人是不受影响的,因为后面的元素都比它矮。
  2. 很重要的一点,相同身高的人,一定是第二个字段小的先来,例如[5,1]和[5,2].前面有[7,0][7,1].
  1. 如果大的先来,先插入[5,2],变成[7,0][7,1][5,2].然后插入[5,1],变成[7,0][5,1],[7,1],[5,2]. 发现了吗,[5,2]前面有3个>=它的,这样就不满足条件了
  2. 如果小的先来,先[5,1]变成[7,0][5,1],[7,1]。然后插入[5,2]变成[7,0][5,1],[5,2],[7,1], 此时才满足条件
代码

在这里插入图片描述

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        Arrays.sort(people, new Comparator<int[]>() {
            @Override
            public int compare(int[] person1, int[] person2) {
               //如果两个人身高不同,身高较高的排前面。第一个字段不同,用第一个字段降序排列
               if(person1[0] != person2[0]) return person2[0] - person1[0];
               //如果两个人身高相同,前面比它高的人数少的排前面。第一个字段相同,按第二个字段升序排列
               //例如 [5,2]和[5,1]正在排序,第一个字段都是5,此时我们想要[5,1]排到[5,2]前面
               else return person1[1] - person2[1];
            }
        });
        //按照身高从高到底排列完成
        //接下来,按顺序操作每个人,这些人的前面的人都比它高
        //当前人物插入到前面,因为前面的人物身高都比他高,不会影响前面这些人物。
        List<int[]> ans = new ArrayList<>();
        for(int[] person:people)
            ans.add(person[1],person);//当前人物,要求必须有几个比它高的人在前面,就把他插入到第几个位置(因为前面的都比它高或和它一样高)
        return ans.toArray(new int[ans.size()][]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值