1、链表的合并
肠子要悔青
leetcode 原题
第一种方法:开辟一个新的链表
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
res=ListNode(0)
p=res#注意这里,p=res 操作res指针,返回p
while l1 and l2:
if l1.val<l2.val:
res.next=l1
l1=l1.next
else:
res.next=l2
l2=l2.next
res=res.next
if l1:
res.next=l1
if l2:
res.next=l2
return p.next
# 构建了一个新的链表,返回什么?返回p.next
# 当两者都存在的时候,进入循环,后面直接接res.next=l1
第二种方法:递归方法
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if not l1:
return l2
if not l2:
return l1
if l1.val<l2.val:
l1.next=self.mergeTwoLists(l1.next,l2)
return l1
else:
l2.next=self.mergeTwoLists(l1,l2.next)
return l2
2、链表的反转
我们可以申请两个指针,第一个指针叫 pre,最初是指向 null 的。
第二个指针 cur 指向 head,然后不断遍历 cur。
每次迭代到 cur,都将 cur 的 next 指向 pre,然后 pre 和 cur 前进一位。
都迭代完了(cur 变成 null 了),pre 就是最后一个节点了。
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre=None
cur=head
while cur:
node=cur.next
cur.next=pre
pre=cur
cur=node
return pre
3、两个链表的第一个公众节点
链表中常用的:快慢双指针
公众节点的判断:双指针浪漫相遇,定义两个指针node1,node2, 依次遍历,直到node1=node2时,是公众节点,node1到达headA的尾部,重新定位到headB的头节点,当node2 到达headB的尾节点时,重新定位到headA的头节点
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
node1,node2=headA,headB
while node1!=node2:
node1=node1.next if node1 else headB
node2=node2.next if node2 else headA
return node1
4、删除链表的节点
leetcode连接
curr.next = curr.next.next 关键在于判读cur.next是否为val, 这样就不需要存储前驱节点了
class Solution:
def deleteNode(self, head: ListNode, val: int) -> ListNode:
pre=ListNode(0)
pre.next=head
if head.val==val: return head.next
while head.next:
if head.next.val==val:
head.next=head.next.next
break
head=head.next
return pre.next
5、链表中倒数第k个节点
设置s,f 快慢指针,f比s快k步,当快指针到达尾部时,慢指针指向的位置即为倒数第k个节点。
leetcode链接
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
if not head: return head
p1=p2=head
for i in range(k-1):
p2=p2.next
while p2.next:
p1=p1.next
p2=p2.next
return p1