[路飞]_leetcode-面试题 17.14-最小K个数

简介: leetcode-面试题 17.14-最小K个数

网络异常,图片无法展示
|


[题目地址][B站地址]


设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。


示例:


输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
复制代码


提示:


  • 0 <= len(arr) <= 100000
  • 0 <= k <= min(100000, len(arr))


sort


解题思路


本题要求返回最小的 k 个数,可以直接对数组元素进行升序排序,返回排序后的前 k 个元素即可。


代码实现


var smallestK = function(arr, k) {
  arr.sort((a,b) => a-b)
  // 返回排序后的前 k 个数字
  return arr.slice(0,k)
};
复制代码


大顶堆


解题思路


涉及到维护最值的问题,都可以利用 来做,这里因为需要维护 k 个最小值,所以需要一个大顶堆。


首先创建一个大顶堆实例,并传入 k,当堆中元素超出 k 个的时候,弹出堆顶元素。


遍历输入数组,如果堆中元素数量不满 k 个,或者当前元素小于堆顶元素,则将其插入堆中。


数组遍历完成,堆中就保存了前 k 个最小的数,将堆中元素返回即可。


代码实现


// 大顶堆
class MaxHeap{
  constructor(max){
    this.size = 0;
    this.list = [];
    this.max = max;
  }
  // 插入元素
  push(val){
    this.list.push(val);
    this.size++;
    // 插入后自下向上平衡调整
    if(this.size>1){
      let cur = this.size-1,
      parent = (cur-1)>>1;
      while(cur>0&&this.list[parent]<this.list[cur]){
        [this.list[parent],this.list[cur]] =
        [this.list[cur],this.list[parent]]
        cur = parent,parent = (cur-1)>>1;
      }
    }
    // 如果当前堆中元素超出了 k 个,弹出堆顶元素
    if(this.size>this.max) this.pop();
  }
  // 弹出元素
  pop(){
    // 弹出堆顶元素,并将最后一个元素占位到堆顶
    this.list[0] = this.list.pop();
    // 弹出后自上向下平衡调整
    let cur = 0,
    childl = 1,childr = 2;
    while(
      (childl<this.size&&this.list[cur]<this.list[childl])||
      (childr<this.size&&this.list[cur]<this.list[childr])
    ){
      if(childr<this.size&&this.list[childl]<this.list[childr]){
        [this.list[cur],this.list[childr]] =
        [this.list[childr],this.list[cur]]
        cur = childr
      }else{
        [this.list[cur],this.list[childl]] =
        [this.list[childl],this.list[cur]]
        cur = childl
      }
      childl = cur*2+1,childr = cur*2+2;
    }
  }
  // 获取堆顶元素
  top(){
    return this.list[0]
  }
}
var smallestK = function(arr, k) {
  // 实例化大顶堆
  const heap = new MaxHeap(k);
  // 遍历输入数组
  for(let i = 0;i<arr.length;i++){
    // 如果堆中元素不够 K 个或者当前元素小于堆顶元素,则插入堆中
    if(heap.size<k||arr[i]<heap.top()){
      heap.push(arr[i])
    }
  }
  // 返回堆中维护的最小的 k 个数
  return heap.list;
};
复制代码


至此我们就完成了 leetcode-面试题 17.14-最小K个数


如有任何问题或建议,欢迎留言讨论!

相关文章
|
3月前
|
开发者 索引 Python
这些年背过的面试题——LeetCode
本文是技术人面试系列LeetCode篇,一文带你详细了解,欢迎收藏!
|
4月前
|
Python
155. 最小栈 力扣 python 空间换时间 o(1) 腾讯面试题
155. 最小栈 力扣 python 空间换时间 o(1) 腾讯面试题
|
4月前
|
存储 算法 索引
1124. 表现良好的最长时间段 (python) 前缀和 分类讨论 最大长度 力扣 面试题
1124. 表现良好的最长时间段 (python) 前缀和 分类讨论 最大长度 力扣 面试题
|
4月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
5月前
|
存储 算法 数据挖掘
深入解析力扣168题:Excel表列名称(进制转换法详解及模拟面试问答)
深入解析力扣168题:Excel表列名称(进制转换法详解及模拟面试问答)
|
5月前
|
存储 算法 数据挖掘
深入解析力扣166题:分数到小数(模拟长除法与字符串操作详解及模拟面试问答)
深入解析力扣166题:分数到小数(模拟长除法与字符串操作详解及模拟面试问答)
|
5月前
|
SQL 算法 大数据
深入解析力扣176题:第二高的薪水(子查询与LIMIT详解及模拟面试问答)
深入解析力扣176题:第二高的薪水(子查询与LIMIT详解及模拟面试问答)
|
5月前
|
算法 数据挖掘 大数据
深入解析力扣172题:阶乘后的零(计算因子5的方法详解及模拟面试问答)
深入解析力扣172题:阶乘后的零(计算因子5的方法详解及模拟面试问答)
|
5月前
|
算法 数据挖掘 大数据
深入解析力扣171题:Excel表列序号(进制转换法详解及模拟面试问答)
深入解析力扣171题:Excel表列序号(进制转换法详解及模拟面试问答)
|
5月前
|
算法 数据挖掘 Java
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)