代码随想录算法训练营Day 04|链表Part02|24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、160. 链表相交、142.环形链表II
文章目录
24. 两两交换链表中的节点
一、Temp保存临时节点
# 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 swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 指针需要指向需要操作的两个节点的前一个节点才能将两个节点交换
dummyhead = ListNode(next = head)
cur = dummyhead
# 链表size为偶数,cur.next为空循环结束,奇数要多一个next
# dummmy>1>2>3>4
while(cur.next!=None and cur.next.next!=None):
temp = cur.next.next.next #保存3的信息
temp1 = cur.next.next #保存2的信息
cur.next.next.next = cur.next #2的next变为1,此时丢掉了3及后面的部分
cur.next.next = temp #1的next变为3,此时丢掉了2的信息
cur.next = temp1 #dummy的next变为2
cur = cur.next.next #更改cur的位置
return dummyhead.next
本方法改变的顺序是2>1>3+d>2。
二、同样是Temp保存临时节点
# 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 swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 指针需要指向需要操作的两个节点的前一个节点才能将两个节点交换
dummyhead = ListNode(next = head)
cur = dummyhead
# 链表size为偶数,cur.next为空循环结束,奇数要多一个next
# dummmy>1>2>3>4
while(cur.next!=None and cur.next.next!=None):
temp = cur.next #保存1的信息
temp1 = cur.next.next.next #保存3的信息
cur.next = cur.next.next #dummyhead的next变为2
cur.next.next = temp #2的next变为1
temp.next = temp1 #1的next变为3
cur = cur.next.next #更新cur位置
return dummyhead.next
这个改变的顺序是d>2>1>3。
三、本题总结
链表的关键就是不能让链表断掉,所以如果指向有改变就要考虑是否有节点因为链表指向改变而丢失,需要考虑使用临时节点来保存信息。这道题不用太纠结更改的步骤,只需要根据对应的步骤保存好丢失的信息就可以了。
19.删除链表的倒数第N个节点
一、快慢指针
# 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 removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummyhead = ListNode(next=head)
# 创建两个指针,慢指针和快指针,并将它们初始化为虚拟节点
fast = dummyhead
slow = dummyhead
# 快指针比慢指针快 n 步
for i in range(n):
fast = fast.next
# 移动两个指针,直到快速指针到达链表的最后一个节点,fast.next为空
while(fast.next):
fast = fast.next
slow = slow.next
# 通过更新第 (n-1) 个节点的 next 指针删除第 n 个节点
slow.next = slow.next.next
return dummyhead.next
这一个方法是提前让fast移动n步,循环条件是fast.next不为空
二、还是快慢指针
# 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 removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummyhead = ListNode(next=head)
# 创建两个指针,慢指针和快指针,并将它们初始化为虚拟节点
fast = dummyhead
slow = dummyhead
# 快指针比慢指针快 n+1 步
for i in range(n+1):
fast = fast.next
# 移动两个指针,直到快速指针到达链表的末尾
while(fast):
fast = fast.next
slow = slow.next
# 通过更新第 (n-1) 个节点的 next 指针删除第 n 个节点
slow.next = slow.next.next
return dummyhead.next
这一个方法是提前让fast移动n+1步,循环条件是fast不为空
三、本题总结
注意range的值即为fast比slow快几步,关键是要让slow停在要删除的节点的上一个节点处。
160. 链表相交
一、法一
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
cur1 = headA
cur2 = headB
size1 = 0
size2 = 0
while cur1:
size1 +=1
cur1=cur1.next
while cur2:
size2 +=1
cur2 =cur2.next
curA = headA
curB = headB
if size2<size1:
curA,curB = headB,headA
size1,size2 = size2,size1
diff = size2-size1
for _ in range(diff): # 让curA和curB在同一起点上(末尾位置对齐)
curB = curB.next
while curA:
if curA != curB:
curA = curA.next
curB = curB.next
else:
return curA
return None
没思路,乱七八糟,记得重写
二、本题总结
注意,交点不是数值相等,而是指针相等。
142. 环形链表 II
一、法一
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
fast = head
slow = head
while(fast!=None and fast.next!=None):
fast = fast.next.next
slow =slow.next
if fast == slow:
index1 = fast
index = head
while(index !=index1):
index =index.next
index1 =index1.next
return index
return None
理解了数学推导,就很好写
二、本题总结
主要在数学方面的逻辑