链表
LC24 两两交换链表中的节点
三指针解决,需要注意改变链表时的指向,避免空指针,遍历过程分3个步骤进行,这里应用了虚拟头节点。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy=ListNode(0,head)
cur=dummy
while(cur.next and cur.next.next):
pre_tmp=cur.next
beh_tmp=cur.next.next.next
cur.next=cur.next.next
cur.next.next=pre_tmp
pre_tmp.next=beh_tmp
cur=cur.next.next
return dummy.next
LC19删除链表的倒数第N个节点
这道题目可以分解成两问,一是到达链表倒数第N个节点的前一节点,然后删除倒数第N个节点。首先快指针先行N步,然后快指针和慢指针同步向右运行,直至快指针到达链表尾部。针对一些特殊情况可以注意一下鲁棒性补充。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
fast,slow=ListNode(0,head),head
#设置快慢指针,快指针先行n步,再快慢指针一起同行直至快指针到达链表尾
i=n
while(i>0):
if fast.next:
fast=fast.next
else:
return
i-=1
print("now_fast:",fast.val)
if fast.next:
fast=fast.next
else:
return head.next
#如果fast指针到了链表末尾,需要去除头节点,直接返回head.next即可
while(fast.next):
fast=fast.next
slow=slow.next
slow.next=slow.next.next
#删除倒数第k个节点
return head
面试题–链表相交
分别求出两链表的长度,通过计算长度差移动指针使得两个链表的尾部对齐进行同步比较。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
ptr_A=headA
ptr_B=headB
len_headA=1
len_headB=1
#如果两个head列表中有一个及以上为空,直接返回
if not ptr_A or not ptr_B:
return
#print("ptr_A:",ptr_A)
#print("ptr_B:",ptr_B)
#如果headA和headB的长度均为1,直接比较两个链表
if not ptr_A.next and not ptr_B.next:
#print("4")
if ptr_A==ptr_B:
#print("3")
return ptr_A
else:
return
#求出A,B两链表的长度
while(ptr_A.next):
len_headA+=1
ptr_A=ptr_A.next
while(ptr_B.next):
len_headB+=1
ptr_B=ptr_B.next
#print("headA:",headA)
#print("headB:",headB)
diff=abs(len_headA-len_headB)
#print("diff:",diff)
#创建新指针,将较长链表向后移动diff距离
#移动完成后,剩下链表的长度相等
new_ptr_A=headA
new_ptr_B=headB
while(diff>0):
if len_headA>len_headB:
#print("1")
new_ptr_A=new_ptr_A.next
#print("new_ptr_A:",new_ptr_A)
diff-=1
else:
#print("2")
new_ptr_B=new_ptr_B.next
#print("new_ptr_B:",new_ptr_B)
diff-=1
#print("new_ptr_A:",new_ptr_A)
#print("new_ptr_B:",new_ptr_B)
#注意这里的条件不能写成new_ptr_A,不然如果两链表不相交会陷入死循环
while(new_ptr_A.next):
#print("99")
#如果移动过的链表相等,即可输出
if new_ptr_A==new_ptr_B:
#print("10")
return new_ptr_B
else:
new_ptr_A=new_ptr_A.next
new_ptr_B=new_ptr_B.next
#print("new_ptr_A:",new_ptr_A)
#print("new_ptr_B:",new_ptr_B)
if new_ptr_A==new_ptr_B:
#print("10")
return new_ptr_B
else:
return
LC142环形链表
这道题的思路需要数学思考较多,首先是用快慢双指针判断是否有环,然后重新定义两个指针,一个从起点出发,每次均前进一步。一个从之前快慢指针的相遇点出发,最终两个指针相遇点即为环的起点。思考时间会多一点,但是代码并没有很复杂。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast,slow=head,head
while(fast and fast.next):
fast=fast.next.next
slow=slow.next
if (fast==slow):
index1=fast
index2=head
while(index1!=index2):
index1=index1.next
index2=index2.next
return index1
return