链表类算法题

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题:有序链表转换二叉搜索树:给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。 本题中,一个高度平衡二叉树是指一个二叉树每个

Leetcode练习(Python):链表类:第206题:反转链表:反转一个单链表。

算法—— 链表类问题

20120918-双向链表类定义《数据结构与算法分析》