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. [计划任务 - Linux]三分钟学会cron

    cron——计划任务,是任务在约定的时间执行已经计划好的工作,是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业. 也就是说cron只适合于linux系统,用windows电脑的同学 ...

  2. [安卓自动化测试] 001.UIAutomator初探

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  3. CSS选择器-类-ID-伪类

    类选择器(Class selectors) 通过设置元素的 class 属性,可以为元素指定类名.类名由开发者自己指定. 文档中的多个元素可以拥有同一个类名. 在写样式表时,类选择器是以英文句号(.) ...

  4. 【Java Spring Cloud 实战之路】- 使用Nacos和网关中心的创建

    0. 前言 在上一节中,我们创建了一个项目架构,后续的项目都会在那个架构上做补充. 1. Nacos 1.1 简介 Nacos可以用来发现.配置和管理微服务.提供了一组简单易用的特性集,可以快速实现动 ...

  5. Java实现 LeetCode 671 二叉树中第二小的节点(遍历树)

    671. 二叉树中第二小的节点 给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0.如果一个节点有两个子节点的话,那么这个节点的值不大于它的子节点的值. 给出这样的 ...

  6. Java实现 蓝桥杯 历届试题 小计算器

    历届试题 小计算器 时间限制:1.0s 内存限制:256.0MB 问题描述 模拟程序型计算器,依次输入指令,可能包含的指令有 1. 数字:'NUM X',X为一个只包含大写字母和数字的字符串,表示一个 ...

  7. Java实现蓝桥杯VIP算法训练 自行车停放

    试题 算法训练 自行车停放 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 有n辆自行车依次来到停车棚,除了第一辆自行车外,每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或 ...

  8. Java实现 蓝桥杯VIP 算法提高 格子位置

    算法提高 格子位置 时间限制:1.0s 内存限制:512.0MB 问题描述 输入三个自然数N,i,j (1<=i<=N,1<=j<=N),输出在一个N*N格的棋盘中,与格子(i ...

  9. C语言深入理解通过指针引用多维数组(指针中使用起始地址 元素地址 元素值的区分)

    #include "pch.h" #include <iostream> #include<stdio.h> int main() { // std::co ...

  10. java实现第七届蓝桥杯方格填数

    方格填数 题目描述 如下的10个格子 +--+--+--+ | | | | +--+--+--+--+ | | | | | +--+--+--+--+ | | | | +--+--+--+ (如果显示 ...