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. spring框架中三层架构相关的注解

    做了这么多年的C++,再去学Java,确实发现,语言都是相通的,即使是Java的那么多生态,理解起来也并不费劲 Spring 框架目前还在学习中,处于 Tourist 阶段,目前只求会做,不求原理,等 ...

  2. Rocket - debug - TLDebugModuleInner - DMSTATUS

    https://mp.weixin.qq.com/s/GyGriFyeq_7Z3xOjKn56Mg 简单介绍TLDebugModuleInner中DMSTATUS寄存器的实现. 1. DMSTATUS ...

  3. Python——day2

    学完今天我保证你自己可以至少写50行代码 明天,还在等你 回顾day1 小练习1: 小练习2: 小练习3: 好了激情的的一天已经过去了正式开始,day2的讲解         Day2 目录: 格式化 ...

  4. Shell 脚本 —— java 代码远程调用shell脚本重启 tomcat

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.创建maven 工程 ​ maven 依赖: <dependency> <grou ...

  5. Java实现 LeetCode 81 搜索旋转排序数组 II(二)

    81. 搜索旋转排序数组 II 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判 ...

  6. Java实现 LeetCode 55 跳跃游戏

    55. 跳跃游戏 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] ...

  7. Android中如何使用自定义对话框

    自定义创建一个XML布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns ...

  8. svg 贝塞尔曲线图解(记录)

    path路径绘制中,绘制贝塞尔曲线的命令包括: Q 二次贝赛尔曲线 x1,y1 x,y T 平滑二次贝塞尔曲线 x,y C 曲线(curveto) x1,y1 x2,y2 x,y S 平滑曲线 x2, ...

  9. Linux笔记(第一天)

    一.命令 lscpu                               -- 查看cpu free                                 -- 内存查看 -m 以M ...

  10. 5.keras-Dropout剪枝操作的应用

    keras-Dropout剪枝操作的应用 1.载入数据以及预处理 import numpy as np from keras.datasets import mnist from keras.util ...