• AC牛客 BM46 最小的K个数


    BM46 最小的K个数

    题目描述

    描述

    给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
    数据范围:0≤k,n≤10000,数组中每个数的大小0≤val≤1000
    要求:空间复杂度O(n) ,时间复杂度 O(nlogk)

    示例1

    输入:
    [4,5,1,6,2,7,3,8],4 
    
    返回值:
    [1,2,3,4]
    
    说明:
    返回最小的4个数即可,返回[1,3,2,4]也可以 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    示例2

    输入:
    [1],0
    
    返回值:
    []
    
    • 1
    • 2
    • 3
    • 4
    • 5

    解题思路

    解法1 排序然后取值

    1.使用冒泡 or 快排 or 堆排序,进行数组排序
    2.遍历数组,取出前面k小元素即可

    解法2 时间复杂度为O(nlogk)的解法

    1.使用冒泡,时间复杂度是o(n^2),堆排序和快排的时间复杂度是O(nlogn),解法要求的时间复杂度和快排很靠近,所以我们只需要考虑,如果优化快排
    2.我们知道快排的思想,是每次选取一个基准值,然后将小于它的元素放到左边,大于它的元素放到右边,那么我们使用这个特性来优化
    3.对比基准值的位置与k

    • 当基准值的位置等于k时,那么直接返回即可,不需要再进行排序,因为此时数组的前k个元素尽管无序,但是已经是最小的k个元素
    • 当基准值的位置大于k时,那么我们只需排序,基准值位置的前半部分即可
    • 当基准值的位置小于k时,那么我们只需排序,基准值位置的后半部分即可
      反复上面的三个步骤,直到k==基准值的位置

    实践代码

    解法 1 代码

    import java.util.ArrayList;
    
    public class Solution {
    	public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
    		ArrayList<Integer> res = new ArrayList<>();
    		if (input == null || input.length <= 0 || k == 0) {
    			return res;
    		}
    
    		quickSort(input, 0, input.length - 1);
    		k = k > input.length ? input.length : k;
    		for (int i = 0; i < k; i++) {
    			res.add(input[i]);
    		}
    		return res;
    	}
    
    	private void quickSort(int[] input, int left, int right) {
    		if (left < right) {
    			int temp = input[left];
    			int i = left;
    			int j = right;
    			while (left < right) {
    				while (left < right && input[right] > temp) {
    					right--;
    				}
    				if (left < right) {
    					input[left] = input[right];
    				}
    				while (left < right && input[left] <= temp) {
    					left++;
    				}
    				if (left < right) {
    					input[right] = input[left];
    				}
    			}
    			input[left] = temp;
    			if (condition) {
    				
    			}
    			quickSort(input, i, left - 1);
    			quickSort(input, left + 1, j);
    		}
    	}
    
    	private void bubbleSort(int[] input) {
    		boolean swap = false;
    		for (int i = 0; i < input.length; i++) {
    			for (int j = 0; j < input.length - i - 1; j++) {
    				if (input[j] > input[j + 1]) {
    					int temp = input[j];
    					input[j] = input[j + 1];
    					input[j + 1] = temp;
    					swap = true;
    				}
    			}
    			if (!swap) {
    				break;
    			}
    		}
    
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    解法2 代码

    import java.util.ArrayList;
    
    public class Solution {
    	public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
    		ArrayList<Integer> res = new ArrayList<>();
    		if (input == null || input.length <= 0 || k == 0) {
    			return res;
    		}
    
    		if (input.length > k) {
    			quickSort(input, 0, input.length - 1, k);
    		}
    		
    		k = k > input.length ? input.length : k;
    		for (int i = 0; i < k; i++) {
    			res.add(input[i]);
    		}
    		return res;
    	}
    
    	private void quickSort(int[] input, int left, int right, int k) {
    		if (left < right) {
    			int temp = input[left];
    			int i = left;
    			int j = right;
    			while (left < right) {
    				while (left < right && input[right] > temp) {
    					right--;
    				}
    				if (left < right) {
    					input[left] = input[right];
    				}
    				while (left < right && input[left] <= temp) {
    					left++;
    				}
    				if (left < right) {
    					input[right] = input[left];
    				}
    			}
    			input[left] = temp;
    			if (left == k) {
    				return;
    			} else if (left < k) {
    				quickSort(input, left + 1, j, k);
    			} else {
    				quickSort(input, i, left - 1, k);
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
  • 相关阅读:
    刷题日常计~JS①
    WPF开源的一款免费、开箱即用的翻译、OCR工具
    大数据 Hive 数据仓库介绍
    【CCF CSP-20161203】权限查询
    C++:模板进阶
    Linux动静态库
    jvm永久代配置
    【java学习】对象的创建和使用(14)
    保护您的 Web 应用程序的最佳开源 Web 应用程序防火墙
    软件架构师考试的真实感受
  • 原文地址:https://blog.csdn.net/baobei0921/article/details/127766054