1. 题目

2. 解答

2.1. 方法一——大顶堆

参考 堆和堆排序 以及 堆的应用,我们将数组的前 K 个位置当作一个大顶堆。

首先建堆,也即对堆中 [0, (K-2)/2] 的节点从上往下进行堆化。第 K/2 个节点若有子节点,其左子节点位置应该为 2 * K/2 + 1 = K+1,而我们堆中的最大位置为 K-1,显然第 K/2 个节点是第一个叶子节点,不用堆化。

建完堆之后,我们顺序访问原数组 [k, n-1] 位置的元素,如果当前元素小于堆顶元素也就是位置为 0 的元素,那么删除堆顶元素并将当前元素插入堆中。

最后,堆中的 K 个元素即为所求。

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { if (k > input.size())
{
vector<int> result;
return result;
}
Build_Heap_K(input, k);
vector<int> result(input.begin(), input.begin()+k);
return result;
} void Build_Heap_K(vector<int> &input, int k)
{
// input 的 [0, k-1] 作为一个大小为 K 的大顶堆
// 然后从上往下进行堆化
// 也就是对堆中 [0, (k-2)/2] 的节点进行堆化
for (int i = (k-2)/2; i >= 0; i--)
Heapify(input, k, i); // 遍历 input 的 [k, n-1] 的元素
// 如果某元素小于堆顶值,将其插入堆中
// 也即将其替换为堆顶元素,堆化之
for (int i = k; i < input.size(); i++)
{
if (input[i] < input[0])
{
input[0] = input[i];
Heapify(input, k, 0);
}
}
} void Heapify(vector<int> &input, int k, int i)
{
while(1)
{
int max_pos = i;
if (2*i+1 < k && input[2*i+1] > input[max_pos])
max_pos = 2 * i + 1;
if (2*i+2 < k && input[2*i+2] > input[max_pos])
max_pos = 2 * i + 2;
if (max_pos == i)
break;
else
{
int temp = input[max_pos];
input[max_pos] = input[i];
input[i] = temp;
}
i = max_pos;
}
}
};
2.2. 方法二——快排分治

可参考 LeetCode 215——数组中的第 K 个最大元素

快排的时候需要分区,分区点左边的元素都小于主元,分区点右边的元素都大于主元。如果分区后主元的位置恰好为 K,那左边正好是最小的 K 个数;如果大于 K,我们需要递归在左边找到第 K 个位置;如果小于 K,我们则需要递归在右边找到第 K 个位置。

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int n = input.size();
if (k > n)
{
vector<int> result;
return result;
}
Quick_Sort(input, 0, n-1, k);
vector<int> result(input.begin(), input.begin()+k);
return result;
} void Quick_Sort(vector<int> &input, int left, int right, int k)
{
if (left < right)
{
int pivot = input[right];
int i = left;
int j = left; for (; j < right; j++)
{
if (input[j] < pivot)
{
int temp = input[i];
input[i] = input[j];
input[j] = temp;
i++;
}
}
input[j] = input[i];
input[i] = pivot; if (i == k) return;
else if (i > k) Quick_Sort(input, left, i-1, k);
else Quick_Sort(input, i+1, right, k);
}
}
};

获取更多精彩,请关注「seniusen」!

剑指 Offer——最小的 K 个数的更多相关文章

  1. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)

    注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...

  2. 剑指Offer——最小的K个数

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 分析: 建一个K大小的大根堆,存储最小的k个数字. 先将K个数进堆 ...

  3. python剑指offer最小的K个数

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 思路: 使用快排中的partition思想. ①我们设定part ...

  4. 用js刷剑指offer(最小的K个数)

    题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 牛客网链接 js代码 function GetLeastNumbe ...

  5. 剑指offer--10.最小的K个数

    边界判断,坑了一下 ----------------------------------------------- 时间限制:1秒 空间限制:32768K 热度指数:375643 本题知识点: 数组 ...

  6. 剑指Offer-29.最小的K个数(C++/Java)

    题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 分析: 最先想到的是将数组升序排列,返回前k个元素.不过排序的话效率 ...

  7. 剑指:最小的k个数

    题目描述 输入 n 个整数,找出其中最小的 K 个数.例如输入 4,5,1,6,2,7,3,8 这 8 个数字,则最小的 4 个数字是 1,2,3,4. 解法 解法一 利用快排中的 partition ...

  8. 2-剑指offer: 最小的K个数

    题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 代码: // 这种topN问题比较常见的是使用堆来解决,最小的k个 ...

  9. 剑指Offer28 最小的K个数(Partition函数应用+大顶堆)

    包含了Partition函数的多种用法 以及大顶堆操作 /*********************************************************************** ...

随机推荐

  1. PHP 如何实现页面静态化

    页面静态化分为两种 一种伪静态,即url重写,一种纯静态化. 一.静态化的优点: 1有利于搜索引擎收录网站页面的信息:搜索引擎更喜欢静态的,更变于抓取,搜索引擎SEO排名会更容易提高. 2静态网页化网 ...

  2. Python生成文本格式的excel\xlwt生成文本格式的excel\Python设置excel单元格格式为文本\Python excel xlwt 文本格式

    Python生成文本格式的excel\xlwt生成文本格式的excel\Python设置excel单元格格式为文本\Python excel xlwt 文本格式 解决: xlwt 中设置单元格样式主要 ...

  3. 14-jquery元素节点操作

    **创建节点** ```var Div = $('<div>');var Div2 = $('<div>这是一个div元素</div>');``` **插入节点** ...

  4. iOS手势操作,拖动,轻击,捏合,旋转,长按,自定义(http://www.cnblogs.com/huangjianwu/p/4675648.html)

    1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureReco ...

  5. MAKEDEV - 建立设备

    总览 (SYNOPSIS) cd dev; ./MAKEDEV -V cd dev; ./MAKEDEV [ -n ] [ -v ] update cd dev; ./MAKEDEV [ -n ] [ ...

  6. do{}while(0);里面有continue

    do{}while(0);里面有continue,退出的只是do{}while(0);

  7. connect to SQL Server in python on centos

    在centos 6.5 下python使用pyodbc连接sql server 报错: [unixODBC][Driver Manager]Can't open lib 'SQL Server'... ...

  8. 运算符、流程控制(if、while)笔记

    目录 算术运算符 比较运算符(返回一个bool值) 逻辑运算符(把多个条件同时叠加) 赋值运算符 身份运算符 位运算符 成员运算符 python运算优先级 流程控制:向一个方向变化 if判断 单分支结 ...

  9. linux运维、架构之路-python2.6升级3.6

    一.环境 1.系统 [root@m01 ~]# cat /etc/redhat-release CentOS release 6.9 (Final) [root@m01 ~]# uname -r -. ...

  10. Python自动化运维技术与最佳实现

    第一章 系统基础信息模块详解 系统基础信息采集模块最为监控模块的重要组成部分,能够帮助运维人员了解当前系统的健康程度,同时也是衡量业务的服务质量的依据,比如系统资源吃紧,会直接影响业务的质量以及用户的 ...