Leetcode刻意练习----数组5
题目
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明
给定的 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:
a = 0
c = ListNode(0)
c.next = head
d = head
while d != None:
a += 1
d = d.next
d = c
b = a - n
while b > 0:
d = d.next
b -= 1
d.next = d.next.next
return c.next
在看了一些题解之后又发现了以下两种算法,且均为一次遍历
方法二(双指针)
运用双指针,首先先将第一个指针移动到第n+1位,使得两个指针之间相差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:
a = ListNode(0)
a.next = head
b = a
c = a
for i in range(0, n + 1):
b = b.next
while b != None:
b = b.next
c = c.next
c.next = c.next.next
return a.next
方法三(递归)
# 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:
global count
count = 0
if head == None:
return None
head.next = self.removeNthFromEnd(head.next, n)
count += 1
return head.next if count == n else head