LeetCode:链接
参考链接:点这里
Given a linked list, remove the n-th node from the end of list and return its head.
Example:
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Follow up:
Could you do this in one pass?
remind me: 快慢指针思想。先设定一个dummy node,快慢指针同时走dummy node出发。快指针先走n步,然后快慢指针同时走,直到快指针走到链表末尾。此时慢指针的下一个节点就是要删除的节点。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
'''随机初始化一个值 可以有next指针 和head连上'''
dummy = ListNode(-1)
dummy.next = head
'''将fast和slow指针都定义成dummy'''
fast = slow = dummy
'''先走n步'''
while n and fast:
fast = fast.next
n -= 1
'''fast指针走到末尾 因为slow指针指的不是head 而是head前一个 所以slow指针此时指的就是倒数的前一个'''
while fast.next:
fast = fast.next
slow = slow.next
'''重新连接'''
slow.next = slow.next.next
'''返回的不是head 因为有可能会出现空的情况'''
return dummy.next
下面的是常规做法,思路清晰但是容易漏判。
这道题和剑指offer链表题剑指Offer_编程题14:链表中倒数第k个结点很像。有两种做法,一种是先遍历得到链表的长度,然后减去n;还有一种就是快指针走n-1步,然后一起走,等他到尾结点了另一个指针也走到了倒数的第n个结点。
需要注意的是,如果链表只有一个值,那么去掉重复的就是空,如果倒数的第n个结点是头结点,那么去掉重复的得返回head.next。我感觉自己的思路是对的,但是也反复修改了好几次才做对。 Runtime只打败了45.1%的人。还需要反复判断是否是头结点和尾结点。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
if not head or not head.next:
return None
phead = head
for i in range(n-1):
phead = phead.next
if phead == None:
return None
pcur = head
ppre = head
while phead.next:
phead = phead.next
ppre = pcur
pcur = pcur.next
if pcur == head:
head = head.next
else:
ppre.next = pcur.next
return head