题目:给定一个链表,删除链表的倒数第n个节点,再返回链表的头结点。例如给定链表1->2->3->4->5,删除n=2个节点,结果是1->2->3->5
法1:先计算链表长度count,删除倒数第n个,相当于删除正数count-n+1=5-2+1=4个(开头从1开始计),所以要找它前面的那个节点,也就是第3个,在上面的例子中是找到节点3,记为p,将p.next=p.next.next,就相当于删除了p.next
这里注意,如果链表长度count=n,正好是删除第一个节点,直接return head.next即可。为什么要单独拿出来讨论?因为如果链表为单个节点1,n=1时,p.next.next不存在
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
if head==None or n==0:return head
p,count=head,0
while p!=None:
count+=1
p=p.next
if count==n:return head.next #正好是删除正数第一个节点
n=count-n #正数
p=head
while n>1:
p=p.next
n-=1
p.next=p.next.next
return head
法2:快慢指针,快指针从头开始先走n步,慢指针再从头开始,两指针一起走
注意,这里快指针先走n步后,要观察链表长度与n的关系
1)如果fast==None,而n>0,说明快指针已经走到链表尾部了,但还未到 倒数第n个点,此时链表长度<n
2)如果fast==None,而n==0,说明链表长度正好==n,删除的就是链表的头节点
3)链表长度>n的话,比如此时fast指在节点3的位置,让slow从头节点1开始,每次slow与fast都走一步,直到fast指在最后一个节点上,此时slow正好指在要删除的节点的前一个节点上,使得slow.next=slow.next.next
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
if head==None or n==0:return head
fast=head
while n>0 and fast!=None:
fast=fast.next
n-=1
if fast==None and n>0:return head#此时n大于链表长度
if fast==None and n==0:return head.next #n=链表长度
slow=head
while fast.next!=None:
slow=slow.next
fast=fast.next
slow.next=slow.next.next
return head