目录
- 350-两个数组的交集
- 283-移动零
- 1-两数之和
- 25-K 个一组翻转链表
- 581-最短无序连续子数组
- 合并区间
- 螺旋矩阵
- 数组中相加和为0的三元组
- 数组中出现次数超过一半的数字
- 字符串出现次数的TopK问题
- 206-反转链表
- 160-相交链表
- 19-删除链表的倒数第N个节点
- 21-合并两个有序链表
- 31-下一个排列
- 链表K位翻转
- 链表排序-归并算法
- 判断链表中是否有环
- 设计LRU缓存结构
- 两个链表的第一个公共结点
- 两个链表生成相加链表
- 合并N个有序链表
- 链表内指定区间反转
最小的K个数
访问量:1394
一、简介
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
数据范围:0\le k,n \le 100000≤k,n≤10000,数组中每个数的大小0 \le val \le 10000≤val≤1000
要求:空间复杂度 O(n)O(n) ,时间复杂度 O(nlogn)O(nlogn)
示例1
输入:
[4,5,1,6,2,7,3,8],4
返回值:
[1,2,3,4]
说明:
返回最小的4个数即可,返回[1,3,2,4]也可以
题目来源:牛客
二、解法
知识点:堆、排序、分治
package main type Heap struct { size int // 大小 data []int // 数据 } func GetLeastNumbers_Solution( input []int , k int ) []int { // write code here if k == 0 || len(input) == 0 { return nil } // 构建一个大小为 k的大堆 minHeap := new(Heap) minHeap.size = k for _,v := range input { minHeap.Add(v) } return minHeap.data } func (h *Heap) Add(v int) { if len(h.data) == 0 { h.data = []int{v} return } if len(h.data) < h.size { // 堆尚未满 h.data = append(h.data, v) middleIndex := len(h.data) / 2 - 1 for i := middleIndex; i>= 0; i -- { h.jumpData(i) } return } // 堆已满 if h.data[0] <= v {// 若当前元素,大于堆顶元素,则丢失 return } // 移除堆顶元素 h.data[0] =v // 调整堆中元素 h.jumpData(0) } func (h *Heap) jumpData(index int) { leftIndex := 2*index +1 rightIndex := 2 *index + 2 if leftIndex >= len(h.data) { return } if rightIndex >= len(h.data) { // 仅仅有左边节点 if h.data[leftIndex] < h.data[index] { return } // 交换左边节点和 当前节点 h.data[leftIndex], h.data[index] = h.data[index], h.data[leftIndex] // 调整 leftIndex节点 h.jumpData(leftIndex) return } // 根节点已是最大值 if h.data[index] >= h.data[leftIndex] && h.data[index] >= h.data[rightIndex] { return } // left 节点是最大值 if h.data[leftIndex] > h.data[index] && h.data[leftIndex] >= h.data[rightIndex] { // 交换左边节点和 当前节点 h.data[leftIndex], h.data[index] = h.data[index], h.data[leftIndex] // 调整 leftIndex节点 h.jumpData(leftIndex) return } // right 节点是最大值 if h.data[rightIndex] > h.data[index] && h.data[rightIndex] >= h.data[leftIndex] { // 交换左边节点和 当前节点 h.data[rightIndex], h.data[index] = h.data[index], h.data[rightIndex] // 调整 leftIndex节点 h.jumpData(rightIndex) return } }
本文为原创文章,请尊重辛勤劳动,如需转载,请保留本文地址
若您感觉本站文章不错,读后有收获,不妨赞助一下?
我要赞助