开始学习算法力扣。
学习流程
1. 先看了labuladong老师的文字版,然后手敲:时间空间复杂度入门 | labuladong 的算法笔记
2. 然后看了哔哩哔哩:11_LeetCode力扣算法:分隔链表(python编码实现)_哔哩哔哩_bilibili
3. 自己写力扣链表方面的题。
基本原理
单向链表
class ListNode:
def __init__(self,x):
self.val = x
self.next = None
创建链表
1. 直接创建。
head = ListNode(1)
head.next = ListNode(2)
2. 工具函数创建。
def createLinkedList(arr:'List[int]')-> 'ListNode':
if arr is not None or len(arr) == 0:
return None
head = ListNode(arr[0])
cur = head
for i in range(1,len(arr)):
cur.next = ListNode(arr[i])
cur = cur.next
return head
打印链表
head = createLinkedList([1,2,3,4,5])
p = head
while p is not None:
print(p.val)
p = p.next
修改链表
head = createLinkedList([1,2,3,4,5])
# 在头部插入一个新元素
newNode = ListNode(0)
newNode.next = head
head = newNode
# 在尾部插入一个新元素
newNode1 = ListNode(6)
cur = head
while cur != None:
cur = cur.next
cur.next = newNode1
# 在中间插入一个新元素
newNode2 = ListNode(3)
# 假如插入到第二个元素后面
i = 2
cur = head
while i > 0:
i=i-1
cur = cur.next
newNode2.next = cur.next.next
cur.next = newNode2
# 删除头节点
head = head.next
# 删除尾节点
cur = head
while cur.next.next is not None:
cur = cur.next
cur.next.next = cur.next
# 删除中间节点(假设删除第三个)
i = 3
cur = head
while i > 1:
i = i-1
cur = cur.next
cur.next = cur.next.next
双向链表
class DoublyListNode:
def __init__(self,prev,element,next):
self.val = element
self.next = next
self.prev = prev
创建链表
def createDoublyList(arr:list[int]) -> Optional[DoublyListNode]:
if not arr:
return None
head = DoublyListNode(arr[0])
cur = head
for val in arr[1:]:
new_node = DoublyListNode(val)
cur.next = new_node
new_node.prev = cur
cur = cur.next
return head
打印链表
head = createDoublyList([1,2,3,4,5])
tail = None
# 从前往后打印
cur = head
while cur is not None:
print(cur.val)
tail = cur
cur = cur.next
# 从后往前打印(tail在上面已经移动到了最后)
cur = tail
while cur is not None:
print(cur.val)
cur = cur.prev
修改链表
head = createDoublyList([1,2,3,4,5])
# 头部插入元素
new_head = DoublyListNode(0)
new_head.next = head
head.prev = new_head
head = new_head
# 尾部插入新元素
cur = head
while cur is not None:
cur = cur.next
new_tail = DoublyListNode(6)
new_tali.prev = cur.prev
cur = new_tail
# 中间插入新元素
cur = head
i = 3
newNode = DoublyListNode(8)
while i > 0:
i = i-1
cur = cur.next
newNode.next = cur.next
cur.next = newNode
newNode.prev = cur
# 中间删除某个元素
cur = head
i = 3
while i > 1:
i = i-1
cur = cur.next
cur.next = cur.next.next
cur.next.prev = cur
# 删除第一个元素
head = head.next
head.prev = None
# 删除最后一个元素
tail = head
while tail.next is not None:
tail = tail.prev
tail.next = None
leetcode代码
我自己写的不一定是最优解,请参考专业的版本。
21.合并两个有序列表
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
def mergeTwoLists(self, list1, list2):
"""
:type list1: Optional[ListNode]
:type list2: Optional[ListNode]
:rtype: Optional[ListNode]
"""
dummy = ListNode(-1)
cur = dummy
while list1 and list2:
if list1.val < list2.val:
cur.next = list1
list1 = list1.next
else:
cur.next = list2
list2 = list2.next
cur = cur.next
if list1:
cur.next = list1
if list2:
cur.next = list2
return dummy.next
876.链表的中间节点
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
def middleNode(self, head):
"""
:type head: Optional[ListNode]
:rtype: Optional[ListNode]
"""
fast = head
low = head
while fast and fast.next is not None:
fast = fast.next.next
low = low.next
return low
160.相交链表
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
lenA = lenB = 0
curA, curB = headA, headB
while curA:
lenA += 1
curA = curA.next
while curB:
lenB += 1
curB = curB.next
curA, curB = headA, headB
if lenA > lenB:
for _ in range(lenA - lenB):
curA = curA.next
else:
for _ in range(lenB - lenA):
curB = curB.next
while curA and curB:
if curA is curB:
return curA
curA = curA.next
curB = curB.next
return None
141.环形链表
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
fast = head
low = head
while fast is not None and fast.next is not None:
fast = fast.next.next
low = low.next
if fast == low:
return True
return False
86.分隔链表
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def partition(self, head, x):
"""
:type head: Optional[ListNode]
:type x: int
:rtype: Optional[ListNode]
"""
big = ListNode(-1)
small = ListNode(-1)
smallhead , bighead = small ,big
cur = head
while cur:
if cur.val < x:
small.next = cur
small = small.next
else:
big.next = cur
big = big.next
cur = cur.next
big.next = None
small.next = bighead.next
return smallhead.next