• 算法练习-排序 LeetCode 剑指 Offer 40. 最小的k个数


    今日心情:感觉做过的题还是不会 😮‍💨😮‍💨

    题目描述:

     LeetCode 剑指 Offer 40. 最小的k个数

    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。


    解题代码:

    1. class Solution {
    2. public int[] getLeastNumbers(int[] arr, int k) {
    3. process(arr,0,arr.length-1);
    4. int[] res = new int[k];
    5. for(int i = 0; i < k ; i++){
    6. res[i] = arr[i];
    7. }
    8. return res;
    9. }
    10. public void process(int[] arr, int L, int R){
    11. if(L >= R){return;}
    12. int[] equalRange = partition(arr,L,R);
    13. process(arr,L,equalRange[0]-1);
    14. process(arr,equalRange[1]+1,R);
    15. }
    16. public int[] partition(int[] arr, int L, int R){
    17. int index = L;
    18. int lessR = L-1;
    19. int moreR = R;
    20. while(index < moreR){
    21. if(arr[index] < arr[R]){
    22. swap(arr,++lessR,index++);
    23. }else if(arr[index] > arr[R]){
    24. swap(arr,--moreR,index);
    25. }else{
    26. index++;
    27. }
    28. }
    29. swap(arr,moreR,R);
    30. return new int[]{lessR+1,moreR};
    31. }
    32. public void swap(int[] arr, int i,int j){
    33. int temp = arr[i];
    34. arr[i] = arr[j];
    35. arr[j] = temp;
    36. }
    37. }

    解题思路:

    采用快排对整个数组进行升序排序

    (1)将整个数组按照最后一个数据进行大小划分,大的放在右边,小的放在左边。

            -- 设置范围L 左边起始位置, R右边终点位置,lessR = L-1 小于最后一个数的指标,moreR =R 大于最后一个数的指标。

            -- 从 index = L 开始,以数组最后一个数为判断标准,如果当前index所指的数小于最后一个数,将,lessR加一,与index位置的数进行互换,实际上该数位置不变,然后index加1. 如果当前index所指的数大于最后一个数,此时moreR减1,index不变,对两个位置上的数进行交换。如果相等则index加1,移动index继续判断下一个数。

           -- 当 index == moreR 的时候,说明所有交换完成,退出循环。注意此时最后一个数需要和moreR换位置。

           --  返回 lessR+1 和 moreR 值,进行下一次递归的范围判断。

    1. public int[] partition(int[] arr, int L, int R){
    2. int index = L;
    3. int lessR = L-1;
    4. int moreR = R;
    5. while(index < moreR){
    6. if(arr[index] < arr[R]){
    7. swap(arr,++lessR,index++);
    8. }else if(arr[index] > arr[R]){
    9. swap(arr,--moreR,index);
    10. }else{
    11. index++;
    12. }
    13. }
    14. swap(arr,moreR,R);
    15. return new int[]{lessR+1,moreR};
    16. }

            交换函数 

    1. public void swap(int[] arr, int i,int j){
    2. int temp = arr[i];
    3. arr[i] = arr[j];
    4. arr[j] = temp;
    5. }

    (2)递归函数:(对不等于最后一个数的左右两段进行排序,递归实现整个数组的升序排序)

            -- 退出递归条件:L与R边界撞上的时候

            -- 获取左右边界范围(equalRange[0] 是 lessR+1 ,即等于最后一个数的第一个下标范围,equalRange[1] 是moreR , 即等于最后一个数的最后一个下标范围

            -- 对于不等于最后一个数的左右范围进行递归

                递归的左边范围: L 到 equalRange[0]-1        

                递归的右边范围 :equalRange[1]+1 到 R

    1. public void process(int[] arr, int L, int R){
    2. if(L >= R){return;}
    3. int[] equalRange = partition(arr,L,R);
    4. process(arr,L,equalRange[0]-1);
    5. process(arr,equalRange[1]+1,R);
    6. }

    (3)调用递归函数对数组进行升序排序,然后输出前k个数,即为当前数组中前k个最小的值


  • 相关阅读:
    2021 AAAI best Paper - Informer-2020 学习记录
    计网面试题
    【自然语言处理】深度学习基础
    年产1万吨L-赖氨酸干粉工厂的设计-发酵工段及车间的设计(lunwen+CAD图纸)
    团队开发(git的使用及注意事项)
    MIT课程分布式系统学习04——PrimaryBackup Replication for Fault Tolerance
    自定义类型:结构体,枚举,联合的学习
    比较两个数组内容是否相同
    h3c OSPF和ISIS双点双向引入配置
    架构核心技术之微服务架构
  • 原文地址:https://blog.csdn.net/qq_41758969/article/details/125455057