最小的K个数(数组)
来源:互联网 发布:鼠标自动点击软件 mac 编辑:程序博客网 时间:2024/06/15 00:42
题目描述:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
思路一:
import java.util.ArrayList;import java.util.Arrays;public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { ArrayList<Integer> list = new ArrayList<>(); if (input.length <= 0 || k <= 0 || k > input.length) return list; Arrays.sort(input); for (int i = 0; i < k; i++) list.add(input[i]); return list; }}
思路二:
快排,时间复杂度为O(NlogN)~O(N^2),空间复杂度为O(logN)~O(N)
import java.util.ArrayList;public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { ArrayList<Integer> list = new ArrayList<>(); if (input.length <= 0 || k <= 0 || k > input.length) return list; QuickSort(input, 0, input.length - 1); for (int i = 0; i < k; i++) list.add(input[i]); return list; } private void QuickSort(int[] arr, int low, int high) { int index; while (low < high) { index = partition(arr, low, high); QuickSort(arr, low, index - 1); low = index + 1; //优化1:避免了尾递归 } } private int partition(int[] arr, int low, int high) { int flag = arr[low]; while(low < high) { while (low < high && arr[high] >= flag) high--; arr[low] = arr[high]; while(low < high && arr[low] <= flag) low++; arr[high] = arr[low]; } arr[low] = flag; return low; }}
思路三:
堆排序
构建一个大顶堆的时间复杂度为O(N),重建大顶堆的时间复杂度为O(NlogN),总时间复杂度为O(NlogN)
空间复杂度O(1)
import java.util.ArrayList;public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { ArrayList<Integer> list = new ArrayList<>(); if (input.length <= 0 || k <= 0 || k > input.length) return list; HeapSort(input); for (int i = 0; i < k; i++) list.add(input[i]); return list; } private void HeapSort(int[] arr) // 从小到大排序,建立一个大顶堆;从大到小排序,建立一个小顶堆 { for (int i = arr.length/2-1; i >=0; i--) //非终端节点的范围0~length/2-1 { HeapAdjust(arr, i, arr.length); } for (int i = arr.length - 1; i >= 0; i--) { swap(arr, 0, i); HeapAdjust(arr, 0, i); } } private void HeapAdjust (int[] arr, int s, int m) { int temp = arr[s]; int j = 2 * s + 1; for (; j <= m - 1; j = 2 * j + 1) { if (j < m - 1 && arr[j] < arr[j + 1]) ++j; if (temp >= arr[j]) break; arr[s] = arr[j]; s = j; } arr[s] = temp; } private void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }}
思路四:
改进的堆排序
对数组的前k个数建立一个大顶堆,将剩余N-K个数,依次与堆顶比较,若比堆顶小,则替换堆顶,再调整堆。最终将堆里的k个数加入列表中。
建立一个大顶堆的时间复杂度为O(k),调整大顶堆的时间复杂度为O((N-k)logk),总的时间复杂度为O(Nlogk)
空间复杂度为O(k+1)即O(k)
最后输出的k个数可以不按照从小到大输出
import java.util.ArrayList;public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { ArrayList<Integer> list = new ArrayList<>(); if (input.length <= 0 || k <= 0 || k > input.length) return list; HeapSort(input, k); for (int i = 0; i < k; i++) list.add(input[i]); return list; } private void HeapSort(int[] arr, int k) // 从小到大排序,建立一个大顶堆;从大到小排序,建立一个小顶堆 { int[] karr = new int[k]; for (int i = 0; i < k; i ++) karr[i] = arr[i]; for (int i = k/2-1; i >=0; i--) //非终端节点的范围0~length/2-1 { HeapAdjust(karr, i, k);// // karr为大顶堆 } for (int i = k; i < arr.length; i++) { if (arr[i] < karr[0]) { karr[0] = arr[i]; HeapAdjust(karr, 0, k); } } for (int i = 0; i < k; i++) arr[i] = karr[i]; } private void HeapAdjust (int[] arr, int s, int m) { int temp = arr[s]; int j = 2 * s + 1; for (; j <= m - 1; j = 2 * j + 1) { if (j < m - 1 && arr[j] < arr[j + 1]) ++j; if (temp >= arr[j]) break; arr[s] = arr[j]; s = j; } arr[s] = temp; }}
import java.util.ArrayList;public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { ArrayList<Integer> list = new ArrayList<>(); if (input.length <= 0 || k <= 0 || k > input.length) return list; HeapSort(input, k); for (int i = 0; i < k; i++) list.add(input[i]); return list; } private void HeapSort(int[] arr, int k) // 从小到大排序,先建立一个大顶堆;从大到小排序,先建立一个小顶堆 { int[] karr = new int[k]; for (int i = 0; i < k; i ++) karr[i] = arr[i]; for (int i = k/2-1; i >=0; i--) //非终端节点的范围0~length/2-1 { HeapAdjust(karr, i, k); } for (int i = k; i < arr.length; i++) { if (arr[i] < karr[0]) { karr[0] = arr[i]; HeapAdjust(karr, 0, k); } } for (int i = k - 1; i >= 0; i--)//加循环 { swap(karr, 0, i); HeapAdjust(karr, 0, i); } for (int i = 0; i < k; i++) arr[i] = karr[i]; } private void HeapAdjust (int[] arr, int s, int m) { int temp = arr[s]; int j = 2 * s + 1; for (; j <= m - 1; j = 2 * j + 1) { if (j < m - 1 && arr[j] < arr[j + 1]) ++j; if (temp >= arr[j]) break; arr[s] = arr[j]; s = j; } arr[s] = temp; } private void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }}
阅读全文
0 0
- 最小的K个数(数组)
- 数组------最小的k个数
- 数组中最小的K个数
- 求数组中最小的k个数
- 数组中最小的k个数
- 无序数组最小的k个数
- 无序数组中最小的k个数
- 【数组5】最小的K个数
- 找到数组中最小的K个数
- 无序数组中最小的K个数
- 无序数组中最小的k个数
- 无序数组中的最小的k个数
- 找出数组中最小的 K 个数
- 无序数组中最小的k个数
- 剑指offer_数组---最小的K个数
- 无序数组最小的K个数
- 寻找数组中最小的k个数 "最小堆方法"
- 无序数组中找到第K小的数(或者找到最小的K个数)
- 选项卡
- 其他题目---两个有序数组间相加和的TopK问题
- 数字视频质量评价 Video-Quality Metric
- CentOS7.2 安装mysql,并配置自动启动和远程访问
- 添加到Embedded Binaries的框架也需要加到"Link Binary With Libraries"列表
- 最小的K个数(数组)
- 破解 geetest(极验)的滑块验证码
- DOM DOM概述
- spark: Task not serializable (java)
- 浅谈安卓自定义view(一):制作一个最最最简单的自定义view
- [Leetcode] 441. Arranging Coins 解题报告
- 简单的多线程多点下载
- Ubuntu中使用virtualenv
- x264-settings