首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >golang刷leetcode 前 K 个高频元素

golang刷leetcode 前 K 个高频元素

作者头像
golangLeetcode
发布2022-08-02 19:17:30
发布2022-08-02 19:17:30
3340
举报

给你一个整数数组 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高频的,我们可以采用小根堆,来做排序

代码语言:javascript
复制
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,所以可以结合快速排序来求结果

源码:

代码语言:javascript
复制
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
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档