题目:
解法1:
- 先把链表转换成list,删除list的倒数第n个值,再把list转换成链表。不过这样做就失去了这道题的意义。具体代码如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
l = []
while head:
l.append(head.val)
head = head.next
del l[len(l)-n]
if len(l)==0:
return
head = ListNode(l[0])
r = head
p = head
for i in l[1:]:
node = ListNode(i) # 新建一个节点
p.next = node # 节点连接到当前链表的尾巴上
p = p.next # 链表指针向后移动
return r
解法2:
- 先遍历一遍链表,得到链表的长度count,进而得到要删除节点正着数的位置,即count-n。
- 再次遍历一遍链表,当遍历到count-n-1时,删除节点,p.next = p.next.next实现删除节点。
- 需要考虑特殊情况:如果要删除的是头结点,那么count-n=0,所以在第二次遍历的时候,count-n-1是取不到的,无法删除,要单独考虑。具体代码如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
count = 0
p=head
while p:
p = p.next
count +=1
target = count-n
if count == n:
return head.next
p1 = head
while target>1:
p1 = p1.next
target-=1
p1.next = p1.next.next
return head
解法3:
- 使用快慢指针,快指针先移动n步,慢指针再从头开始移动,两指针一起走,
直到快指针移动到链表末尾时结束。此时,慢指针对应的就是要删除节点的前一节点。
- 需要考虑一种特殊情况:删除的是头节点。具体代码如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
slow, fast = head, head
while n:
fast= fast.next
n -= 1
if fast is None:
return head.next
while fast.next:
slow = slow.next
fast = fast.next
slow.next = slow.next.next
return head