面试题40:最小的 k 个数
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 个数的更多相关文章
- 剑指offer 面试题40. 最小的k个数
O(N)划分法,注意这个方法会改变原数据(函数参数是引用的情况下)!当然也可以再定义一个新容器对其划分 要求前k小的数,只要执行快排划分,每次划分都会把数据分成大小两拨.直到某一次划分的中心点正好在k ...
- 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 = ...
- 《剑指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 ...
- 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序
剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...
- 剑指 Offer 40. 最小的k个数
剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:ar ...
- 剑指Offer:面试题30——最小的k个数(java实现)
问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...
- 面试题30.最小的k个数
题目:输入n个整数,找出其中最小的k个数,例如输入4,5,1,6,2,7,3,8 这8个数字,则最小的四个数字为1,2,3,4, 这道题是典型的TopK问题,剑指Offer提供了两种方法来实现,一种方 ...
- 【Java】 剑指offer(40) 最小的k个数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...
- 40 最小的K个数(时间效率)
题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 测试用例: 功能测试(输入的数组中有相同的数字:输入的数组中 ...
- 每日一题 - 剑指 Offer 40. 最小的k个数
题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 快排 难易程度:中等 题目描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3. ...
随机推荐
- 盘点Mysql的登陆方式
前置知识 我们想登陆到mysql中前提是肯定需要一个用户名和密码:比如 root root 在mysql中用户的信息会存放在 mysql数据库下的 user表中 可以 use mysql 然后sele ...
- 50个SQL语句(MySQL版) 问题三
--------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 tea ...
- Beta冲刺 —— 5.30
这个作业属于哪个课程 软件工程 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.讨论并解决每个人存在的问 ...
- Rocket - tilelink - Edges
https://mp.weixin.qq.com/s/UggNsNOeEMP-GhzlLiT-qQ 简单介绍Edges的实现. 1. TLEdge 包含client和manage ...
- jchdl - RTL Block
https://mp.weixin.qq.com/s/pR6b6i98P9dRU8bhZkKaww 观察Verilog代码可以发现,对逻辑的描述中都是assign和always代码块.这正对应了硬 ...
- Python——day2
学完今天我保证你自己可以至少写50行代码 明天,还在等你 回顾day1 小练习1: 小练习2: 小练习3: 好了激情的的一天已经过去了正式开始,day2的讲解 Day2 目录: 格式化 ...
- Java实现 LeetCode 423 从英文中重建数字
423. 从英文中重建数字 给定一个非空字符串,其中包含字母顺序打乱的英文单词表示的数字0-9.按升序输出原始的数字. 注意: 输入只包含小写英文字母. 输入保证合法并可以转换为原始的数字,这意味着像 ...
- Java实现 计蒜客 拯救行动
拯救行动 公主被恶人抓走,被关押在牢房的某个地方.牢房用 N \times M (N, M \le 200)N×M(N,M≤200) 的矩阵来表示.矩阵中的每项可以代表道路(@).墙壁(#).和守卫( ...
- Java实现 LeetCode 19删除链表的倒数第N个节点
19. 删除链表的倒数第N个节点 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当 ...
- Java实现构造无向图的欧拉回路( The Necklace)
中文翻译: 但是,唉!一天,项链被撕破了,珠子散落在屋檐上.我姐姐尽力把地板上的珠子都捡起来了.但她不确定自己是否能收集到所有的照片.现在,她来找我帮忙.她想知道是否有可能让克劳斯使用她在里面的所有珠 ...