文章目录
q215 数组中的第k个最大元素
题目传送门
题解
虽然题目要求的是返回数组中的第k个最大元素,但是我建立的是小根堆,因为建立小根堆时,为结果数组赋值是从大到小开始赋值的,即从数组尾开始赋值。所以最后作排序操作遍历时,当len(nums) - i == k 时,直接返回nums[i]即可。
func findKthLargest(nums []int, k int) int {
// 建堆
for i := len(nums) / 2 - 1; i >= 0; i-- {
heapify(nums, len(nums), i)
}
for i := len(nums) - 1; i > 0; i-- {
nums[i], nums[0] = nums[0], nums[i]
heapify(nums, i, 0)
if len(nums) - i == k {
return nums[i]
}
}
return nums[0]
}
func heapify(arr []int, n int, i int) {
//堆的维护
largest := i //i为当前父节点的下标
lson := i * 2 + 1 //左孩子
rson := i * 2 + 2 //右孩子
// 保存最大值的下标
if lson < n && arr[largest] < arr[lson] {
largest = lson
}
if rson < n && arr[largest] < arr[rson] {
largest = rson
}
if largest != i {
arr[largest], arr[i] = arr[i], arr[largest]
// 往孩子节点递归维护堆
heapify(arr, n, largest)
}
}
q347 前k个高频元素
题目传送门
题解
首先用一个hash表来记录每个数字出现的次数,然后开一个二维数组,count[i][0]用来储存给定数组的元素,count[i][1]用来储存给定数组元素的出现次数。接着使用堆排序,根据元素的出现次数进行排序,即根据count[i][1]来建立小根堆,以此来对count数组进行排序。然后将count[i][0]存到res中,最后当len(nums) - i == k 时,返回res即可。做法与上一道题类似。
func topKFrequent(nums []int, k int) []int {
hashTable := make(map[int]int)
for _, v := range nums {
hashTable[v]++
}
var count [][]int
for k, v := range hashTable {
count = append(count, []int{k, v})
}
res := make([]int, 0)
// 建堆
for i := len(count) / 2 - 1; i >= 0; i-- {
heapify(count, len(count), i)
}
for i := len(count) - 1; i >= 0; i-- {
count[i], count[0] = count[0], count[i]
heapify(count, i, 0)
res = append(res, count[i][0])
if len(count) - i == k {
break
}
}
return res
}
func heapify(arr [][]int, n int, i int) {
//堆的维护
largest := i //i为当前父节点的下标
lson := i * 2 + 1 //左孩子
rson := i * 2 + 2 //右孩子
// 保存最大值的下标
if lson < n && arr[largest][1] < arr[lson][1] {
largest = lson
}
if rson < n && arr[largest][1] < arr[rson][1] {
largest = rson
}
if largest != i {
arr[largest], arr[i] = arr[i], arr[largest]
// 往孩子节点递归维护堆
heapify(arr, n, largest)
}
}