题解 | #最小的K个数#

最小的K个数

https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf

利用的是堆排序算法

提前需要了解的知识点:

找出最后一个非叶子节点:(length-1)/2

获取一个父节点的子节点 : (child*2)+1 、(child*2)+2

逻辑大致如下:

1、把列表改造成最小堆,也就是列表的第一个元素是最小值

(1)获取列表里的最后一个非叶子节点。把当前这个节点当作是一棵树,获取该节点下的最大堆。

a、获取列表里的最后一个非叶子节点。定位到这个非叶子节点的两个子节点。

b、判断两个子节点哪个是最小的。

c、把最小的子节点和父节点对比,加入子节点比父节点小,则把他们两替换一下

d、假如最小的子节点没有比父节点小,可以执行退出。

e、假如最小的子节点比父节点小,需要获取把子节点当作父节点,然后找出该节点是否子节点,若有的话,再次调到步骤a进行操作。

(2)for循环,获取前一个叶子节点,当作为父节点,把当前节点的子树如步骤(1)改成成最小堆。

2、把最小的值和列表最后一个值进行替换。

3、根据需要k个值,则循坏k次去获取列表中的最小堆,注意的是每次经过步骤2后,列表最后的k个值则不需要加入到列表排序中,也就是当作列表少了最后k个数。

4、获取最后k个数的值,则是列表中最小的K个值。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param input int整型一维数组 
     * @param k int整型 
     * @return int整型ArrayList
     */
    public ArrayList<Integer> GetLeastNumbers_Solution (int[] input, int k) {
        for(int i =input.length-1;i>input.length-1-k;i--)
        {
             getbiggest(input,i);
        }
        // int[] result = new int[k];
        ArrayList<Integer>  result= new ArrayList<>();

        for(int i = 0;i<k;i++)
        {
            result.add(input[input.length-1-i]);
        }
        return result;
    }


    private void getbiggest(int[] input,int length)
    {
        for(int i = (length-1)/2;i>=0;i--)
        {
            sort(input,i,length);
        }
        int tmp = input[length];
        input[length] = input[0];
        input[0]=tmp;
    }

    private void sort(int[] input, int father, int size)
    {
        //获取父节点的值
        int fatherValue = input[father];
        for(int child = (father*2)+1 ;child<=size; child=(child*2)+1)
        {
            //比较两个子节点、获取值最大的一个
            if(child<size &&  input[child]<input[child+1]){
                child++;
            }
            //比较最大的子节点和父节点
            if(input[child]>input[father])
            {
                int tmp = input[father];
                input[father] = input[child];
                input[child] = tmp;
                father=child;
            }
            else{
                break;
            }
        } 
    }
}

}

#算法提升#
全部评论

相关推荐

03-11 09:14
已编辑
武汉大学 后端工程师
24年6-8月,我的大三暑假,在鹅厂pcg度过了一段难忘的实习时光。那年的面试很顺利,一共面了3家offer了2家,进了组之后同事们都很好,mt是我的校友,至今仍然保持良好关系。后来我放弃了转正机会,因为觉得保研名额来之不易,我觉得硕士毕业后一定可以有更好的工作,更高的工资。可是之后发生的一切却让我始料未及。一年半过去,我会的东西变多了,却从1月起再难以通过任何一家公司的一场面试。目前的我有客户端的实习经历,有后端的知识储备,有agent相关的项目履历,且因研究生阶段师兄带着做科研对大模型相关的知识也有一定的了解。力扣刷了500题,说多不多,说少不少,反正把hot100和灵神题单1700分以下的都做了遍。但为什么自己就是通不过面试呢?客观分析的话有自己不够专精某一方面的因素,每次面试刚开始被问一个点的时候刚开始还OK,面试官接着深入拷打,我就没啥办法了,临场应变能力也不行。说白了:BFS❤️;DFS💔。另外就是自己没有一套很好的学习体系,总是拆东墙补西墙,因为某次面试被拷打项目,就疯狂准备项目相关的知识,忽略了计算机基础,结果下周的另一场面试被面试官计网OS一通轰炸。说了这么多,聊聊我目前的状态吧。很多大厂最近都开放了春招实习的投递,我目前采取的是海投策略。这周的Timeline大概就是周四要再次征战鹅厂,wxg的面试强度想必大家都了解,我也没有抱希望能过,以学习为主吧。周六的团子笔试应该可以试一下,毕竟有两次机会,而且貌似团子不咋看笔试分数?蚂蚁也发了笔试邀请,但因为阿里系今年笔试的改革,打算观望一下第一场的情况再参加。对自己下阶段的期望,就是不要怀疑自身的能力,然后客观评估自己当前的水准,持续进步。感谢大家能看完哥们的碎碎念,祝各位牛友都早日拿到理想offer,我后面也会持续更新自己的面试记录,也欢迎大家来一起交流呀
钱嘛数字而已:"后来我放弃了转正机会,因为觉得保研名额来之不易"--- 转正机会明显比保研名额更来之不易。从保研的比例和大厂offer的通过率,非常容易判断。
今天你投了哪些公司?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务