24 两两交换链表
题目链接:
自己想
1.首先明确交换的抽象就是将当前节点指针指向前一个节点,
2.确定好循环体内的步骤,即每一次要完成哪几步
3.确定好边界条件
看完题解
1.首先就是要引入虚拟头节点cur = new_node(next=head)
2.交换,需要存储一个中间变量,temp = cur.next。交换完毕之后还需要将虚拟头节点移动到cur.next.next。这样又可以开始一次循环,也就是说每一个循环内要完成三个操作:
3.根据上述要完成的操作,可以明确,不仅要找到虚拟头节点的next不为空,还需要保证next.next不为空,因此while(cur.next and cur.next.next)
完整代码
# 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]:
new_node = ListNode(next = head)
cur = new_node
if (cur.next is not None) and (cur.next.next is not None):
while((cur.next is not None) and (cur.next.next is not None)):
temp1 = cur.next
temp2 = cur.next.next.next
cur.next = cur.next.next
cur.next.next = temp1
temp1.next = temp2
cur = temp1
return new_node.next
else:
return new_node.next
19 删除链表的倒数第n
题目链接:
自己想
1.如果线性思考,删除倒数,不仅需要知道链表长度,就需要遍历到尾,然后再遍历一遍找到倒数的n,如何用更好的方法呢?自己没想到
2.删除就是将待删除的节点
3.确定好边界条件是什么呢?
看完题解
1.首先就是要引入虚拟头节点cur = new_node(next=head),为了删除某一个节点,要找到这个节点的前一个节点才行
2.删除使用双指针,双指针间隔为n,这样就能找到了
3.边界条件就是,快指针对应的下一个指针为空指针即可
关键思路衔接
写这个的目的就是以前关键点思路清楚了,但是到具体实现,衔接关键点就会混乱,具体的混乱体现在while,if设置不清楚。
1.为了使快慢指针间隔为n(为的是当快指针在末尾时,慢指针在要删除节点的前一个节点),那么也就是让快指针先走n步,其实就可以先一个while循环,让快指针走到第n步;然后再写一个while(fast)
完整代码
# 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]:
# new_node = ListNode(next = head)
# cur = new_node
# cur1 = new_node
# n1 = 0
# while(cur1):
# cur1 = cur1.next
# n1 += 1
# n2 = n1-n
# if (cur.next is not None):
# while(n2 - 1):
# cur = cur.next
# n2 -= 1
# cur.next = cur.next.next
# return new_node.next
# else: return new_node.next
#双指针
new_node = ListNode(next = head)
fast = new_node
low = new_node
n1 = 0
while(fast.next is not None):
fast = fast.next
print(fast)
n1 += 1
if n1 >= n +1:
low = low.next
print(low)
low.next = low.next.next
return new_node.next
面试题 02.07. 链表相交
题目链接:
自己想
1.链表都不一样长,怎么判断呢?然后就进行不下去了
2.确定好循环体内的步骤,即每一次要完成哪几步
3.确定好边界条件
看完题解(关键思路
1.判断相交,求出A链表与B链表的长度,然后求出差值,先让长链表先走n步,之后两个链表一起前进,当链表A,Bd的下一个指针相等时,即为相交点
思路衔接及细节
并不确定链表A,B那一个长,需要加一个判断条件去更改
完整代码
# 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:
#求得链表1和链表2的长度
cur1 = headA
cur2 = headB
n1,n2 = 0,0
while(cur1):
cur1 = cur1.next
n1 += 1
while(cur2):
cur2 = cur2.next
n2 += 1
# 判断一下长度,让curA一直为最长
cur1 = headA
cur2 = headB
if n2 > n1:
n1,n2 = n2,n1
cur1,cur2 = cur2,cur1
diff_ = n1 - n2
while(diff_):
cur1 = cur1.next
diff_ -= 1
while(cur2):
if cur2 == cur1:
return cur2
else:
cur1 = cur1.next
cur2 = cur2.next
return None
142.环形链表II
题目链接:
自己想
1.如何判断有环,我想的应该就是cur.next一直不为空就可以
2.如何判断环的起点
3.确定好边界条件
看完题解(关键思路
1.判断有环也是定义快慢指针,如果快慢指针相遇即有环
2.判断环的起点是运用了数学知识,假设相遇点,然后找到条件,下图来自代码随想录_环形链表
具体就是x = z,利用这个条件去找环入口
思路衔接及细节
因为fast要一次走两步,所以第一个while(fast.next.next),在此循环里,当if fast==low:设置两个指针利用x=z去寻找对应环入口,在if中还有while(index != index1):
完整代码
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast = head
low = head
while(fast and fast.next):#
fast = fast.next.next
low = low.next
if fast == low:
index = head
index1 = fast
while(index != index1):
index = index.next
index1 = index1.next
return index
return None
收获
1.加深了双指针的应用,在链表相关的题中,要学会使用双指针,例如删除这一操作,在数组和链表中都使用了双指针
2.虚拟头节点的使用,例如在删除链表都一个节点时,要考虑节点的上一个节点,就要想到使用虚拟头节点
3.思路链接性,while,if 懂不懂就搞混,要注意!!!如何明确什么时候用if和while