24. 两两交换链表中的节点
# 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]:
dummynode=ListNode(0,head)
prenode=dummynode
#不能在这里就初始化cur和post 因为我们还不知道pre后面是否有node
while prenode.next!=None and prenode.next.next!=None:
curnode=prenode.next
postnode=prenode.next.next
curnode.next=postnode.next#这里不先做postnode.next=curnode的原因是,这样做还需要再记录post.next的结点,所以先连cur->post.next
postnode.next=curnode
prenode.next=postnode
prenode=prenode.next.next
return dummynode.next
- 自己刚开始没有理清一个一个小的subproblem逐渐扩大到原问题规模的通用规则。我的思路是想把链表的两个两个交换后在反转中间的指针,这样就会存在在边界条件不断出错。
- 可以先考虑长度为3的链表的置换(为什么不考虑长度为2,因为如果长度为2就没有两两组件的指针交换,即怎么跟下一个pair连接起来),然后逐渐扩大。
- 虚拟头指针 dummyNode=pre,交换pre.next(cur)和pre.next.next(post)。pre.next指向翻转后的node,即post。
- 逐渐扩大问题规模,即可以把dummyNode(初始化为prenode)看成已经处理好的前链表的尾结点。
19删除链表的倒数第n个结点
哈哈哈哈哈哈纪念一下第一次这么快速的一次通过中档题!!!!!!小小骄傲一下
需要注意的点是:
在链表的删除问题上,因为会有删除的结点是否是头结点的问题,所以一定要加一个虚拟头结点,这样不容易出错!!!
面试题 02.07. 链表相交
下面是错的
# 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:
#先求出两个链表的各自长度,然后对于短的链表,可以通过添加虚拟结点增加到同一长度,或者长的链表指针移动到两长度之差处
lengtha=0
pointera=headA
while(pointera!=None):
lengtha+=1
pointera=pointera.next
lengthb=0
pointerb=headB
while(pointerb!=None):
lengthb+=1
pointerb=pointerb.next
if(lengtha<=lengthb):
gap=lengthb-lengtha
minhead=headA
maxhead=headB
else:
gap=lengtha-lengthb
minhead=headB
maxhead=headA
count=0
while(count!=gap):
count+=1
maxhead=maxhead.next
min_=ListNode(0,minhead)
max_=ListNode(0,maxhead)
while(1):
min_=min_.next
max_=max_.next
if(min_.val!=max_.val):
continue
else:
p1=min_
p2=max_
while(p1.val==p2.val and p1.next!=None):
p1=p1.next
p2=p2.next
if(p1.next==None):
return min_
elif(p1.val!=p2.val):
min_=p1
max_=p2
if(max_==None):
return None
这个题目是什么意思啊?
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
skipA = 2, skipB = 3用在哪里呢???为什么第一次相交不是1吗?????
我领悟了,该题所传入的链表已经有相交了,即某一部分开始它们共用一个内存地址,比如listA和listB从8开始,后面指向的node串只有一个,即公用。
所以我的代码只是判断了值相等的入口。
另外:
node1=node2表示指向相同的物理地址,node1.val=node2.val才是值相等
while(min_!=None and min_!=max_):
min_=min_.next
max_=max_.next
if(min_==None):
return None
else:
return min_
正确题意的解答应该是将最后一个while修改为上面,即找到了相交点。
142.环形链表II
- 怎么找环?
- 怎么找环的入口
本傻瓜直接看了解析视频
# 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]:
slow=head
fast=head
#不要把while的判断放在slow和fast的赋值之后
#while里的条件写跟none有关的(即判断是否存在),是否相等放在if里判断
#while里的条件,只需要判断:
#1. 快指针是否为空(因为慢指针肯定比慢指针慢)
#2. 快指针的next是否为空(如果快指针的next为空了,next.next肯定为空)
while(fast!=None and fast.next!=None):
slow=slow.next
fast=fast.next.next
if(slow==fast):
meet=slow
break
if(fast==None or fast.next==None):#判断stop的情况是否是因为无环
return None
#meet=fast
print(meet.val)
start=head
while((meet.val==start.val and meet.next==start.next)==False):
meet=meet.next
start=start.next
return meet
好题!!!!!!!!!!!!!!!!
复习的时候要看注释噢(#注释)