剑指Offer系列之「最小的k个数」

news/2024/5/20 0:30:16 标签: 数据结构, 算法, java, 排序算法, 快速排序

最小的K个数

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

方法一:直接排序

直接对数组进行全排序,这种方式总是有效的,但是其实不用全部排序。

时间复杂度:O(nlongn)
空间复杂度:O(1)

方法二:堆排序

时间复杂度:O(nlongk), 插入容量为k的大根堆时间复杂度为O(longk), 一共遍历n个元素
空间复杂度:O(k)

方法二:快排

java">import java.util.*;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        int len = input.length;
        ArrayList<Integer> res = new ArrayList<>();
        if(input == null || len == 0 || k < 0 || k > len-1) return res;
        getK(input, k, 0, len-1);
        for(int i=0; i<k; i++){
            res.add(input[i]);
        }
        return res;
    }
    
    private static void getK(int[] arr, int k, int startIndex, int endIndex){
        int len = arr.length;
        if(arr == null || len == 0 || k > len || startIndex >= endIndex) return;
        int left = startIndex;
        int right = endIndex;
        int pivot = arr[left];
        
        while(left < right){
            while(left < right && arr[right] >= pivot) right--;
            arr[right] = arr[left];
            while(left < right && arr[left] <= pivot) left++;
            arr[left] = arr[right];
        }
        arr[left] = pivot;
        if(k == left) return;
        else if(k < left) getK(arr, k, startIndex, left-1);
        else getK(arr, k, left+1, endIndex);
    }
}

时间复杂度:平均时间复杂度为O(n),每次partition的大小为n+n/2+n/4+... = 2n,最坏时间复杂度为O(n^2), 因为每次partition都只减少一个元素
空间复杂度:O(1)


http://www.niftyadmin.cn/n/1690275.html

相关文章

浅谈「事务 分布式事务」

事务 什么是事务&#xff1f; 事务是逻辑上的一组操作&#xff0c;要么都执行&#xff0c;要么都不执行。 事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账1000元&#xff0c;这个转账会涉及到两个关键操作就是&#xff1a;将小明的余额减少1000元&#xff0…

浅谈聚集索引 非聚集索引

聚集索引 聚集索引表记录的排列顺序和索引的排列顺序一致&#xff0c;数据行的物理顺序与列值&#xff08;一般是主键那一列&#xff09;的逻辑顺序相同&#xff0c;所以查询效率快&#xff0c;只要找到第一个索引值记录&#xff0c;其余就连续性的记录在物理也一样连续存放。…

剑指Offer系列之「丑数」

把只包含质因子 2、3 和 5 的数称作丑数&#xff08;Ugly Number&#xff09;。例如6、8都是丑数&#xff0c;但14不是&#xff0c;因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 也就是说&#xff0c;丑数能够分解成 2x3y5z2^{x}3^{y}…

剑指Offer系列之「数字在升序数组中出现的次数」

统计一个数字在升序数组中出现的次数。 方法一&#xff1a;暴力解 查找数组中某个目标&#xff0c;不管数组是否有序&#xff0c;直接遍历一遍即可。 显然方法一没有把数组有序的条件利用上。 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(1) 方法二&#xff1a;伪二…

剑指Offer系列之「第一次只出现一次的字符」

在一个字符串(0<字符串长度<10000&#xff0c;全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1&#xff08;需要区分大小写&#xff09;.&#xff08;从0开始计数&#xff09; 对于出现次数这种问题&#xff0c;hash表的思想是万能的。 …

剑指Offer系列之「数组中的逆序对」

数组中的逆序对 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 输入描述&#xff1a; 题目保证输入的数组中没有…

剑指Offer系列之「孩子们的游戏(圆圈中最后剩下的数)」

孩子们的游戏&#xff08;圆圈中最后剩下的数&#xff09; 这是一个约瑟夫问题&#xff0c;题解百度上都有&#xff0c;这里直接上代码 public class Solution {public int LastRemaining_Solution(int n, int m) {if(n < 0) return -1;int index 0;for(int i2; i<n; …

剑指Ofeer系列之「和为S的两个数字」

输入一个递增排序的数组和一个数字S&#xff0c;在数组中查找两个数&#xff0c;使得他们的和正好是S&#xff0c;如果有多对数字的和等于S&#xff0c;输出两个数的乘积最小的。 因为数组是有序的&#xff0c;所以可以用双指针&#xff0c;指向数组的首尾&#xff0c;具体步骤…