2025-03-20-02
This commit is contained in:
127
技术/Go/算法相关.md
127
技术/Go/算法相关.md
@@ -3,6 +3,133 @@
|
||||
2^x = 1 << x
|
||||
x/2 x >> 1
|
||||
~~~
|
||||
## 快乐数
|
||||
~~~ go
|
||||
func isHappy(n int) bool {
|
||||
slow, fast := n, step(n)
|
||||
for fast != 1 && slow != fast {
|
||||
slow = step(slow)
|
||||
fast = step(step(fast))
|
||||
}
|
||||
return fast == 1
|
||||
}
|
||||
|
||||
func step(n int) int {
|
||||
sum := 0
|
||||
for n > 0 { //通过循环逐位计算
|
||||
sum += (n%10) * (n%10)
|
||||
n = n/10
|
||||
}
|
||||
return sum
|
||||
}
|
||||
~~~
|
||||
|
||||
## 查找二维数组
|
||||
~~~ go
|
||||
func searchMatrix(matrix [][]int, target int) bool {
|
||||
row := sort.Search(len(matrix), func(i int) bool { return matrix[i][0] > target }) - 1
|
||||
if row < 0 {
|
||||
return false
|
||||
}
|
||||
col := sort.SearchInts(matrix[row], target)
|
||||
return col < len(matrix[row]) && matrix[row][col] == target
|
||||
}
|
||||
~~~
|
||||
|
||||
## LRU缓存
|
||||
~~~ go
|
||||
// 定义LRU缓存结构体,包含当前大小、最大容量、键值对映射表以及双向链表的头尾节点
|
||||
type LRUCache struct {
|
||||
size int // 当前缓存中元素的数量
|
||||
capacity int // 缓存的最大容量
|
||||
cache map[int]*DLinkedNode // 键到节点的映射表,用于快速查找节点
|
||||
head, tail *DLinkedNode // 双向链表的虚拟头节点和虚拟尾节点,便于操作边界条件
|
||||
}
|
||||
|
||||
// 定义双向链表节点结构体,包含键、值以及前后指针
|
||||
type DLinkedNode struct {
|
||||
key, value int // 节点存储的数据键和值
|
||||
prev, next *DLinkedNode // 指向前一个和后一个节点的指针
|
||||
}
|
||||
|
||||
// 初始化一个双向链表节点,仅设置键和值,前后指针默认为nil
|
||||
func initDLinkedNode(key, value int) *DLinkedNode {
|
||||
return &DLinkedNode{
|
||||
key: key,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// 构造函数,创建一个新的LRU缓存实例,并初始化其内部数据结构
|
||||
func Constructor(capacity int) LRUCache {
|
||||
l := LRUCache{
|
||||
cache: make(map[int]*DLinkedNode), // 初始化键值对映射表
|
||||
head: initDLinkedNode(0, 0), // 创建虚拟头节点
|
||||
tail: initDLinkedNode(0, 0), // 创建虚拟尾节点
|
||||
capacity: capacity, // 设置缓存最大容量
|
||||
}
|
||||
l.head.next = l.tail // 将虚拟头节点指向虚拟尾节点
|
||||
l.tail.prev = l.head // 将虚拟尾节点指向虚拟头节点
|
||||
return l // 返回构造好的LRU缓存实例
|
||||
}
|
||||
|
||||
// 根据给定键从LRU缓存中获取对应的值,如果不存在则返回-1
|
||||
func (this *LRUCache) Get(key int) int {
|
||||
if _, ok := this.cache[key]; !ok { // 判断键是否存在于缓存中
|
||||
return -1 // 如果不存在,直接返回-1
|
||||
}
|
||||
node := this.cache[key] // 获取到对应节点
|
||||
this.moveToHead(node) // 将该节点移动到链表头部(表示最近访问)
|
||||
return node.value // 返回节点的值
|
||||
}
|
||||
|
||||
// 向LRU缓存中添加或更新键值对,如果缓存已满,则移除最久未使用的节点
|
||||
func (this *LRUCache) Put(key int, value int) {
|
||||
if _, ok := this.cache[key]; !ok { // 判断键是否已经存在于缓存中
|
||||
node := initDLinkedNode(key, value) // 创建新节点
|
||||
this.cache[key] = node // 将新节点加入到映射表中
|
||||
this.addToHead(node) // 将新节点添加到链表头部(表示最近访问)
|
||||
this.size++ // 增加缓存大小计数
|
||||
if this.size > this.capacity { // 如果缓存大小超过最大容量
|
||||
removed := this.removeTail() // 移除链表尾部节点(最久未使用)
|
||||
delete(this.cache, removed.key) // 删除映射表中对应的键值对
|
||||
this.size-- // 减少缓存大小计数
|
||||
}
|
||||
} else { // 如果键已经存在
|
||||
node := this.cache[key] // 获取到对应节点
|
||||
node.value = value // 更新节点的值
|
||||
this.moveToHead(node) // 将该节点移动到链表头部(表示最近访问)
|
||||
}
|
||||
}
|
||||
|
||||
// 将指定节点添加到双向链表头部
|
||||
func (this *LRUCache) addToHead(node *DLinkedNode) {
|
||||
node.prev = this.head // 设置节点的前驱为虚拟头节点
|
||||
node.next = this.head.next // 设置节点的后继为原头部节点
|
||||
this.head.next.prev = node // 将原头部节点的前驱指向当前节点
|
||||
this.head.next = node // 将虚拟头节点的后继指向当前节点
|
||||
}
|
||||
|
||||
// 从双向链表中移除指定节点
|
||||
func (this *LRUCache) removeNode(node *DLinkedNode) {
|
||||
node.prev.next = node.next // 将前驱节点的后继指向后继节点
|
||||
node.next.prev = node.prev // 将后继节点的前驱指向前驱节点
|
||||
}
|
||||
|
||||
// 将指定节点移动到双向链表头部
|
||||
func (this *LRUCache) moveToHead(node *DLinkedNode) {
|
||||
this.removeNode(node) // 首先移除该节点
|
||||
this.addToHead(node) // 然后将其添加到链表头部
|
||||
}
|
||||
|
||||
// 移除双向链表尾部节点并返回该节点
|
||||
func (this *LRUCache) removeTail() *DLinkedNode {
|
||||
node := this.tail.prev // 获取尾部节点(不包括虚拟尾节点)
|
||||
this.removeNode(node) // 移除该节点
|
||||
return node // 返回被移除的节点
|
||||
}
|
||||
~~~
|
||||
|
||||
## 加油站
|
||||
在一条环路上有 `n` 个加油站,其中第 `i` 个加油站有汽油 `gas[i]` 升。
|
||||
|
||||
|
Reference in New Issue
Block a user