import java.util.Arrays;

/**
* Created by clearbug on 2018/2/26.
*
* 面试题40:最小的 k 个数
*
* 注意:因为前两天在陌陌面试时被问到的问题是最大的 k 个数,所以这里的代码也是求解最大的 k 个数的,最小的 k 个数原理是一样的。
*/
public class Solution { public static void main(String[] args) throws InterruptedException {
Solution s = new Solution(); int[] arr = {1, 2, 3, 11, 8, 10, 5, 4, 22, 66, 23, 20};
System.out.println(Arrays.toString(s.topK1(arr, 5)));
int[] arr2 = {3, 2, 1, 11, 8, 10, 5, 4, 22, 66, 23, 20};
System.out.println(Arrays.toString(s.topK2(arr2, 5)));
} /**
* 方法一就是利用快速排序的思想
*
* 时间复杂度:O(n)
*
* @param arr
* @param k
* @return
*/
public int[] topK1(int[] arr, int k) {
int topK = arr.length - k;
int start = 0;
int end = arr.length - 1;
int index = partition(arr, start, end); while (index != topK) {
if (index > topK) {
end = index - 1;
index = partition(arr, start, end);
} else {
start = index + 1;
index = partition(arr, start, end);
}
} return subArr(arr, topK, arr.length);
} /**
* 方法二就是利用堆排序来解决了
*
* 时间复杂度:O(nlogk)
*
* @param arr
* @param k
* @return
*/
public int[] topK2(int[] arr, int k) {
int[] heap = new int[k];
int heapCount = 0;
for (int i = 0; i < arr.length; i++) {
if (heapCount < k) {
heap[heapCount++] = arr[i];
}
if (heapCount == k) { // 初始化 heap 为小顶堆
heapify(heap);
heapCount++;
continue;
}
if (heapCount > k) {
if (arr[i] > heap[0]) {
heap[0] = arr[i];
// 调整 heap 为小顶堆
adjust(heap, 0);
}
}
}
return heap;
} private void adjust(int[] arr, int i) {
int leftChildIndex = 2 * i + 1;
int rightChildIndex = 2 * i + 2;
int smallestIndex = i;
if (leftChildIndex < arr.length && arr[leftChildIndex] < arr[smallestIndex]) {
smallestIndex = leftChildIndex;
}
if (rightChildIndex < arr.length && arr[rightChildIndex] < arr[smallestIndex]) {
smallestIndex = rightChildIndex;
}
if (smallestIndex != i) {
int temp = arr[i];
arr[i] = arr[smallestIndex];
arr[smallestIndex] = temp;
adjust(arr, smallestIndex);
}
} private void heapify(int[] arr) {
for (int i = arr.length / 2 - 1; i >= 0; i--) {
int leftChildIndex = 2 * i + 1;
int rightChildIndex = 2 * i + 2;
int smallestIndex = i;
if (leftChildIndex < arr.length && arr[leftChildIndex] < arr[smallestIndex]) {
smallestIndex = leftChildIndex;
}
if (rightChildIndex < arr.length && arr[rightChildIndex] < arr[smallestIndex]) {
smallestIndex = rightChildIndex;
}
if (smallestIndex != i) {
int temp = arr[i];
arr[i] = arr[smallestIndex];
arr[smallestIndex] = temp;
}
}
} private int[] subArr(int[] arr, int start, int end) {
int[] res = new int[end - start];
for (int i = start; i < end; i++) {
res[i - start] = arr[i];
}
return res;
} private int partition(int[] arr, int start, int end) {
int privot = arr[start];
while (start < end) {
while (arr[end] >= privot && end > start) {
end--;
}
arr[start] = arr[end];
while (arr[start] <= privot && end > start) {
start++;
}
arr[end] = arr[start];
}
arr[start] = privot;
return start;
}
}

面试题40:最小的 k 个数的更多相关文章

  1. 剑指offer 面试题40. 最小的k个数

    O(N)划分法,注意这个方法会改变原数据(函数参数是引用的情况下)!当然也可以再定义一个新容器对其划分 要求前k小的数,只要执行快排划分,每次划分都会把数据分成大小两拨.直到某一次划分的中心点正好在k ...

  2. leetcode 签到 面试题40. 最小的k个数

    题目 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k = ...

  3. 《剑指offer》面试题40. 最小的k个数

    问题描述 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k ...

  4. 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序

    剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...

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

    剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:ar ...

  6. 剑指Offer:面试题30——最小的k个数(java实现)

    问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...

  7. 面试题30.最小的k个数

    题目:输入n个整数,找出其中最小的k个数,例如输入4,5,1,6,2,7,3,8 这8个数字,则最小的四个数字为1,2,3,4, 这道题是典型的TopK问题,剑指Offer提供了两种方法来实现,一种方 ...

  8. 【Java】 剑指offer(40) 最小的k个数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...

  9. 40 最小的K个数(时间效率)

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,.   测试用例: 功能测试(输入的数组中有相同的数字:输入的数组中 ...

  10. 每日一题 - 剑指 Offer 40. 最小的k个数

    题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 快排 难易程度:中等 题目描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3. ...

随机推荐

  1. 基本的sql-select语句

    插入三张表: @d:/del_data.sql;                   @d:/hr_cre.sql;                   @d:/hr_popul.sql;select ...

  2. windows下grunt的快速入门

    1.认识grunt  grunt是什么:他是一套前端自动化工具,是一个基于nodejs的命令行工具.(Grunt和Grunt插件是通过npm  安装并管理的,所以首先要安装nodejs). grunt ...

  3. Spring boot Sample 009之spring-boot-web-thymeleaf

    一.环境 1.1.Idea 2020.1 1.2.JDK 1.8 二.目的 spring boot 整合thymeleaf模板开发web项目 三.步骤 3.1.点击File -> New Pro ...

  4. Autofac依赖注入

    简介 Autofac 是一款超赞的.NET IoC 容器 . 它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改 .它的实现方式是将常规的.net类当做 组件 处理. ...

  5. 非阻塞赋值(Non-blocking Assignment)是个伪需求(2)

    https://mp.weixin.qq.com/s/5NWvdK3T2X4dtyRqtNrBbg   13hope: 个人理解,Verilog本身只是“建模”语言.具体到阻塞/非阻塞,只规定了两种赋 ...

  6. Chisel3 - Tutorial - Adder

    https://mp.weixin.qq.com/s/SEcVjGRL1YloGlEPSoHr3A   位数为参数的加法器.通过FullAdder级联实现.   参考链接: https://githu ...

  7. Java实现 LeetCode 657 机器人能否返回原点(暴力大法)

    657. 机器人能否返回原点 在二维平面上,有一个机器人从原点 (0, 0) 开始.给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束. 移动顺序由字符串表示.字符 move[i ...

  8. Java实现 LeetCode 15 三数之和

    15. 三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以 ...

  9. Java实现 LeetCode_0048_RotateImage

    package javaLeetCode.medium; public class RotateImage_48 { public static void main(String[] args) { ...

  10. Java实现第十届蓝桥杯求和

    试题 A: 求和 本题总分:5 分 [问题描述] 小明对数位中含有 2.0.1.9 的数字很感兴趣,在 1 到 40 中这样的数包 括 1.2.9.10 至 32.39 和 40,共 28 个,他们的 ...