IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 加工并存储数据的数据结构-优先队列 -> 正文阅读

[数据结构与算法]加工并存储数据的数据结构-优先队列

数据结构指的是存储数据的方式。用不同的方式存储数据,可以对数据做不同的高效操作。

堆分为小顶堆和大顶堆,顾名思义,最小/大的为根节点,每次Pop()操作可以获取根节点元素。

堆的操作的时间复杂度为O(logn)

基于数组的堆实现(Go)

type heap struct {
	nums []int
	sz   int // 节点编号
}

func (h *heap) Push(x int) {
	// 节点的编号
	i := h.sz
	h.sz++
	for i > 0 {
		parent := (i - 1) / 2

		if h.nums[parent] <= x {
			break
		}

		h.nums[i] = h.nums[parent]
		i = parent
	}
	h.nums[i] = x
}

func (h *heap) Pop() int {
	ret := h.nums[0]
	h.sz--
	x := h.nums[h.sz]
	i := 0
	for i*2+1 < h.sz {
		a, b := i*2+1, i*2+2
		if b < h.sz && h.nums[b] < h.nums[a] {
			a = b
		}
		if h.nums[a] >= x {
			break
		}
		h.nums[i] = h.nums[a]
		i = a
	}
	h.nums[i] = x
	return ret
}

基于标准库的堆实现(Go)

type hp []int

func (h hp) Len() int { return len(h) }

// Less中,小于为小顶堆,大于为大顶堆
func (h hp) Less(i, j int) bool  { return h[i] < h[j] }
func (h hp) Swap(i, j int)       { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(x interface{}) { *h = append(*h, x.(int)) }
func (h *hp) Pop() interface{}   { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

func main() {
	h := hp{}
	heap.Init(&h)
	heap.Push(&h, 3)
	heap.Push(&h, 5)
	heap.Push(&h, 1)
	for len(h) > 0 {
		fmt.Printf("%v\n", heap.Pop(&h))
	}
}

可以运用优先队列解决的题目

例一:Expedition

请添加图片描述
请添加图片描述

思路:在到达加油站 i i i时,等同于获得了在之后的任何时候都可以加 B i B_i Bi?单位汽油的一次权利。为了加油次数最少,当燃料为0时,则选择加油量最大的加油站。

具体地说:

  • 经过加油站时,往优先队列里加入 B i B_i Bi?
  • 当燃料空时,如果优先队列也空,则无法到达终点。否则取出优先队列中最大的元素加油。

简洁地说:每到一个加油站,就把油买下来放在你的车里,当你没有油了,就加最大的桶。到达终点时,问你加了多少桶。

package main

import (
	"container/heap"
	"fmt"
)

var N, L, P int
var A, B = []int{}, []int{}

func solve() {
	h := hp{}
	heap.Init(&h)
	ans, pos := 0, 0
	for i := 0; i < N; i++ {
		// 前进的距离
		d := A[i] - pos

		// 不断加油直到油量足够行驶到下一个加油站
		for P-d < 0 {
			if len(h) == 0 {
				fmt.Println(-1)
				return
			}
			P += heap.Pop(&h).(int)
			ans++
		}
		P -= d
		pos = A[i]
		heap.Push(&h, B[i])
	}
	fmt.Println(ans)
}

func main() {
	N, L, P = 4, 25, 10
	A = []int{10, 14, 20, 21}
	B = []int{10, 5, 2, 4}
	solve()
}

type hp []int

func (h hp) Less(i, j int) bool  { return h[i] > h[j] }
func (h hp) Swap(i, j int)       { h[i], h[j] = h[j], h[i] }
func (h hp) Len() int            { return len(h) }
func (h *hp) Push(v interface{}) { *h = append(*h, v.(int)) }
func (h *hp) Pop() interface{}   { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

例二:Fence Repair

在这里插入图片描述

在贪心算法中,每次取出最短的两个木板,然后求和再放进去。因此,可以利用优先队列,每次取出两个最小的元素。

Go语言有逃逸机制分析,因此不用像C/C++、Java等语言一样,声明全局变量来减少内存的消耗。

package main

import (
	"container/heap"
	"fmt"
)

func main() {
	// N := 3
	L := []int{8, 5, 8}
	h := hp{}
	heap.Init(&h)
	for _, num := range L {
		heap.Push(&h, num)
	}
	ans := 0
	for len(h) > 1 {
		l1, l2 := heap.Pop(&h).(int), heap.Pop(&h).(int)
		ans += (l1 + l2)
		heap.Push(&h, l1+l2)
	}
	fmt.Println(ans)
}

type hp []int

func (h hp) Less(i, j int) bool  { return h[i] < h[j] }
func (h hp) Swap(i, j int)       { h[i], h[j] = h[j], h[i] }
func (h hp) Len() int            { return len(h) }
func (h *hp) Push(v interface{}) { *h = append(*h, v.(int)) }
func (h *hp) Pop() interface{}   { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

Leetcode的练习题

1046:最后一块石头的重量

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-07 22:56:50  更:2022-04-07 22:58:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:04:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码