
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
1 <= nums.length <= 105
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
解法一:
解题思路
1,将数组转化成数字、频次对
2,对于k高频的,我们可以采用小根堆,来做排序
func topKFrequent(nums []int, k int) []int {
m:=make(map[int]int)
for _,n:=range nums{
m[n]++
}
h:=&heap{
cap:k,
}
for k,v:=range m{
h.push(d{num:k,count:v})
}
var v []int
for _,i:=range h.data{
v=append(v,i.num)
}
return v
}
type d struct{
num int
count int
}
type heap struct {
data []d
cap int
}
func (h*heap)push(da d){
if len(h.data)>=h.cap{
if da.count<=h.data[0].count{
return
}
h.data[0]=da
h.adjust(0)
return
}
h.data=append(h.data,da)
if len(h.data)==h.cap{
for k:=h.cap/2;k>=0;k--{
h.adjust(k)
}
}
}
func (h *heap)adjust(i int){
for i<h.cap {
l:=2*i+1
r:=2*i+2
if r<h.cap{
if h.data[l].count<h.data[r].count && h.data[l].count< h.data[i].count{
h.data[i],h.data[l]= h.data[l],h.data[i]
i=l
}else if h.data[r].count< h.data[i].count{
h.data[i],h.data[r]= h.data[r],h.data[i]
i=r
}else{
break
}
}else if l< h.cap && h.data[l].count< h.data[i].count{
h.data[i],h.data[l]= h.data[l],h.data[i]
i=l
}else{
break
}
}
}源码:
解法二:
解题思路
1,将数组转化成数字、频次对
2,我们知道快速排序的复杂度是nlogn,且每一次排序后,pivot前面的元素都比pivot大,后面的都比pivot小
3,类比这个思路:
A,pivot==k,pivot前面的元素就是所求,得解
B,pivot>k,我们继续在0到 pivot 之间寻找
C,pivot<k 我们在pivot 和len之间寻找
4,所以可以结合快速排序来求结果
源码:
func topKFrequent(nums []int, k int) []int {
if len(nums)<=1{
return nums
}
m:=make(map[int]int)
for _,n:=range nums{
m[n]++
}
var data []d
for k,v:=range m{
data=append(data,d{num:k,cnt:v})
}
fmt.Println(m,data)
if len(data)<=k{
return getNum(data)
}
adjust(data,0,len(data)-1,k)
return getNum(data[:k])
}
func adjust(data[]d,start,end,t int){
if start <0 ||end>len(data)-1{
return
}
l:=start
r:=end
for l<r{
for l<r{
if data[l].cnt>=data[r].cnt{
r--
}else{
data[l],data[r]=data[r],data[l]
break
}
}
for l<r{
if data[r].cnt<=data[l].cnt{
l++
}else{
data[r],data[l]=data[l],data[r]
break
}
}
}
if l+1==t{
return
}
if l+1<t{
adjust(data,l+1,end,t)
return
}
adjust(data,start,r-1,t)
}
func getNum(da[]d)[]int{
var r []int
for _,v:=range da{
r=append(r,v.num)
}
return r
}
type d struct{
num int
cnt int
}本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!