目录
24.两两交换链表中的结点
用虚拟头结点,这样会方便很多。题目链接/文章讲解/视频讲解: 代码随想录
思路
这道题有点思路,但是不多。一开始想的和Carl哥的想法差不多,但是具体几个结点之间的赋值先后顺序还是很容易混乱,加上我这菜的一批的编码能力,还是没能自己完成。。。
先附上Carl哥的图,我觉得很生动形象。(实操让你自己写出来就又是另外一回事了qwq)
推理比较需要思考,看懂了推理看代码就很容易了。
代码
from typing import Optional
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy_head = ListNode(0, head)
cur = dummy_head
# 必须有cur的下一个和下下个才能交换,否则说明已经交换结束了
while cur.next and cur.next.next:
# 建议自己拿纸模拟一次就懂了
temp_1 = cur.next
temp_2 = cur.next.next.next
cur.next = cur.next.next
# 注意下面这里的cur.next.next所指示的和上一行不一样了,cur.next在上一行已经被赋值成cur.next.next了
cur.next.next = temp_1
temp_1.next = temp_2
# 记得移动指针
cur = cur.next.next
return dummy_head.next
19.删除链表倒数第N个结点
双指针的操作,要注意,删除第N个节点,那么当前遍历的指针一定要指向第N个节点的前一个节点。题目链接/文章讲解/视频讲解:代码随想录
思路
这道题如果链表有给前驱节点就很容易了,关键是没有啊家人们!!!
经过一番胡乱思考,我以为可以先遍历一次,看看这个链表有多长,然后再遍历一次正着数到我要删的那个节点,把他删掉。(理论存在,估计得超时,就不试了)
看了Carl哥思路,只能说,我真的题刷太少了,双指针还能这么用:如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。
直接上代码了,思路就是上面那么个思路,代码要注意的点已经注释了。
代码
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
from typing import Optional
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy_head = ListNode(0, head)
fast = dummy_head
slow = dummy_head
for _ in range(n): # 要删除倒数第n个,就让fast指针从虚拟头结点出发先走n步,自己拿纸模拟。
fast = fast.next
while fast.next:
fast = fast.next
slow = slow.next
#下面这一行直接让slow的next跳过我要删的那个结点,连接到slow.next.next,删除成功。
slow.next = slow.next.next
#返回头结点
return dummy_head.next
面试题0207.链表相交
题目链接/文章讲解:代码随想录
思路
首先注意,相交不是指值相等,而是指两个结点指针相等(指针相等,值肯定也相等,反过来就不一定了)。
菜鸟就是这样,想了半天还是想不出来。(希望二刷甚至以后一见到就能立刻想起来思路吧)
Carl哥的题解是这样的:先求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 对齐的位置(如图所示)
此时就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。否则循环退出返回空指针。
只能说妙,真是的妙妙蛙吃着妙脆角妙进了米奇妙妙屋妙到家了,为什么要先把指针A移动到和B对齐呢?我后知后觉才发现,那如果两个链表在某个结点相交了,那后面的长度得是一样的,比如A=[2,6,4,3,8] B=[6,4] ,这样只能说B包含于A中吧。
代码(有点简陋,链接里的写的更优美)
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
cnt_1 = 0
cnt_2 = 0
tempA = headA
tempB = headB
while tempA:
cnt_1 += 1
tempA = tempA.next
while tempB:
cnt_2 += 1
tempB = tempB.next
if cnt_1 >= cnt_2:
distance = cnt_1 - cnt_2
for _ in range(distance):
headA = headA.next
for _ in range(cnt_2):
if headA == headB:
return headA
else:
headA = headA.next
headB = headB.next
elif cnt_1 < cnt_2:
distance = cnt_2 - cnt_1
for _ in range(distance):
headB = headB.next
for _ in range(cnt_1):
if headA == headB:
return headA
else:
headA = headA.next
headB = headB.next
return None
142.环形链表II
算是链表比较有难度的题目,需要多花点时间理解 确定环和找环入口
题目链接/文章讲解/视频讲解:代码随想录
思路
这道题不想写了,我还要写今天的呢。(崩溃)
只能说,这道题很考验你的数理逻辑和推断能力。
直接听Carl讲吧。