链表 - leetcode 总结
思考方式
区别笔试 和 面试
笔试:时间复杂度最低,AC就可,不必纠结空间复杂度
面试:时间复杂度最低,同时空间复杂度也要低,(笔者简称 -- 我全都要(低),其中面试主要考察 ==
在不增加时间复杂度下,降低空间复杂度
重要工具模板
几个重要的工具 (或技巧):快慢指针, dummy 哨兵, 哈希表
#### 快慢指针 ####
fast = slow = head
while fast.next and fast.next.next:
fast = fast.next.next
slow = slow.next
#### dummy 哨兵 ####
# 主要在 head 头节点前增加一个虚拟的节点, 常常
dummy = node0 = ListNode(next=head)
#### 哈希表 ####
# 主要就是用来快速通过,放弃一定的空间
基础水题 - 常见题型
大话说这些题目是水题,是因为:先从内心战胜它们。
一些其他的题目,可以分解成基础水题。
因此,要做到十分熟练。
206 反转链表 , 141. 环形链表,146. LRU 缓存
#### 206 反转链表 ####
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
curr = head
pre = None
while curr:
temp = curr.next # 存一下,原始后继,存后继,下面就要用后继
curr.next = pre # 当前节点逆序
pre = curr # 存当前节点,供下次使用
curr = temp # 往下
return pre
#### 141 环形链表 ####
# 重点学习其中的快慢指针
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
if not head or not head.next: return False
fast = slow = head
while fast.next and fast.next.next:
fast = fast.next.next
slow = slow.next
if fast == slow: return True
return False
手写LRU
class Node:
def __init__(self, key=0, value=0):
self.key = key
self.value = value
self.pre = None
self.next = None
class LRUCache:
def __init__(self, capacity):
self.cache = {}
self.size = 0
self.capacity = capacity
self.head = Node()
self.tail = Node()
self.head.next = self.tail
self.tail.pre = self.head
def get(self, key):
if key not in self.cache.keys():
return -1
node = self.cache.get(key)
self.move_to_head(node)
return node.value
def put(self, key, value):
if key in self.cache.keys():
node = self.cache.get(key)
node.value = value
self.move_to_head(node)
else:
node = Node(key=key, value=value)
self.cache[key] = node
self.add_to_head(node)
self.size += 1
if self.size > self.capacity:
node = self.remove_tail()
self.cache.pop(node.key)
self.size -= 1
def move_to_head(self, node):
self.remove_node(node)
self.add_to_head(node)
def remove_node(self, node):
node.pre.next = node.next
node.next.pre = node.pre
def add_to_head(self, node):
node.next = self.head.next
node.pre = self.head
self.head.next = node
node.next.pre = node
def remove_tail(self):
node = self.tail.pre
self.remove_node(node)
return node