链表类算法题
Posted Kris_u
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表类算法题相关的知识,希望对你有一定的参考价值。
1、反转链表leetcode 206:
// ListNode Definition for singly-linked list.
type ListNode struct
Val int
Next *ListNode
func reverseList(head *ListNode) *ListNode
if head == nil || head.Next == nil
return head
var prev *ListNode
cur := head
for cur != nil
cur.Next, prev, cur = prev, cur, cur.Next
return prev
2、LRU缓存 leetcode
LRU,全称是 Least Recently Used,即最近最少使用。是一种缓存淘汰策略算法。
算法的思想:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。所以,当指定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。
参考:
链接:https://leetcode-cn.com/problems/lru-cache/solution/jian-dan-shi-li-xiang-xi-jiang-jie-lru-s-
type Node struct
key, val int
prev, next *Node
func initNode(key, val int) *Node
return &Node
key: key,
val: va,
type DlinkList struct
head, tail *Node
size int //链表元素数
func initDlinkList() *DlinkList
dll := &DlinkList
head: initNode(0, 0),
tail: initNode(0, 0),
size: 0,
dll.head.next = dll.tail
dll.tail.prev = dll.head
return dll
//在链表尾部添加新节点
func (dl *DlinkList) addNode(x *Node)
x.next = dl.tail
x.prev = dl.tail.prev
dl.tail.prev.next = x
dl.tail.prev = x
dl.size++
//删除链表中的x节点
func (dl *DlinkList) del(x *Node)
x.prev.next = x.next
x.next.prev = x.prev
x.prev, x.next = nil, nil
dl.size--
//删除链表中的第一个节点,并返回该节点
func (dl *DlinkList) delFirstnode() *Node
if dl.head.next == dl.tail.prev
return
first := dl.head.next
dl.del(first)
return first
//双链表只能从尾部插入,尾部节点是最近使用的,靠近头部的数据是最久使用的
type LRUCache struct
capacity int
keyMap map[int]*Node
cache *DlinkList
func initLRUCache(capacity int) LRUCache
lru := LRUCache
capacity: capacity,
keyMap: map[int]*Node,
cache: initDlinkList(),
return lru
func (lru *LRUCache) makeRecentNode(key int)
node := lru.keyMap[key]
lru.cache.del(node) //删除旧的key的节点
lru.cache.addNode(node) //添加到链尾
//在链表尾部添加新节点
func (lru *LRUCache) addRecentNode(key, value int)
node := initNode(key, value)
lru.cache.addNode(node) //添加至双链表
lru.keyMap[key] = node //添加至字典
// 删除某一个 key 及对应元素
func (lru *LRUCache) delKey(key int)
node := lru.keyMap[key]
lru.cache.del(node) //删除双向链表中的key节点
delete(lru.keyMap[key]) //删除字典中的key节点
// 删除最近最少使用的元素
func (lru *LRUCache) deleteLRU()
// 链表的第一个就是最近最少使用的元素
delFirstNode := lru.cache.delFirstnode()
// 删除映射
delete(lru.knMap, delFirstNode.key)
func (lru *LRUCache) Get(key int) int
node, exist := lru.keyMap[key]
if !exist
return -1
lru.makeRecentNode(key)
return node.val
/*
①若节点key已经存在,删除旧的节点,再添加到链尾
②若节点不存在缓存容量已满,则删除使用最少的节点,添加到链尾
③链尾节点数据是最新的
*/
func (lru *LRUCache) Put(key, value int)
_, exist := lru.keyMap[key]
if exist
lru.delKey(key) //删除旧节点
else
if lru.capacity == lru.cache.size
lru.deleteLRU()
lru.addRecentNode(key, value) //链尾数据是最新的
以上是关于链表类算法题的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode练习(Python):链表类:第23题:合并K个排序链表:合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
Leetcode练习(Python):链表类:第109题:有序链表转换二叉搜索树:给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。 本题中,一个高度平衡二叉树是指一个二叉树每个