1、基本思路给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
由于本人自己实现了一个链表类。因此,读者首先需要去 第一篇博客复制链表父类代码(否则代码太长了)。首先统计链表长度,然后正向删除第 length-n 个节点即可。
代码# -*- coding: utf-8 -*-
# ======================================================
# @Time : 2021/01/11
# @Author : lele wu
# @Email : 2541612007@qq.com
# @File : delete_n_node.py
# @Comment: 删除链表中倒数第n个节点
# ======================================================
'''
题目描述:
给定一个链表,删除链表中倒数第n个节点,并且返回头结点.
基本思路:
首先统计链表长度,然后-n看看删除的是正向的那个节点。这样就容易了。
'''
from lianbiao import lianbiao
class DeleteNNode(lianbiao):
def __init__(self):
super(DeleteNNode, self).__init__()
def delete_n_node(self,n):
# 统计链表的长度
pointer = self.head # 由于需要返回头结点,因此需要保存
length = 0
while pointer:
pointer = pointer.getNext()
length+=1
# 初始化
pointer = self.head
# 找出正向需要删除的节点
if n >= length: # 若大于长度,说明删除第一个节点
self.head = self.head.getNext()# 令head指向后一个节点
else:
if n == 1: # 删除尾部节点
for i in range(length-2):
pointer = pointer.getNext()
pointer.setNext(None) # 令尾部节点为None
else: # 删除中间节点
for i in range(length-n-1):
pointer = pointer.getNext()
pointer.setNext(pointer.getNext().getNext()) #指向下一个的下一个节点
return self.head
if __name__ == '__main__':
mylb = DeleteNNode()
mylb.add(9)
mylb.add(1)
mylb.add(5)
mylb.add(4)
mylb.delete_n_node(1)
print([ele for ele in mylb.show()])
2、进阶思路
利用两个间隔长度为n的指针,整体往前遍历,直到最后一个节点。则前面指针所指的就是待删除的节点。
代码# -*- coding: utf-8 -*-
# ======================================================
# @Time : 2021/01/11
# @Author : lele wu
# @Email : 2541612007@qq.com
# @File : delete_n_nodeV2.py
# @Comment:
# ======================================================
'''
题目描述:
给定一个链表,删除链表中倒数第n个节点,并且返回头结点.且扫描一次
基本思路:
用双指针的思想。先让一个指针往前走n个位置。
'''
from lianbiao import lianbiao
class DeleteNNode(lianbiao):
def __init__(self):
super(DeleteNNode, self).__init__()
def delete_n_node(self,n):
left = right = self.head
# 让right指针往前移动n个位置
si = 0
while si < n:
right = right.getNext()
si += 1
if right == None: # 若right == None,说明删除第一个节点
self.head = self.head.getNext()
return self.head
# 当前 right != None,则将两个指针往前移动至链表末尾
while right.getNext() != None:#
left = left.getNext()
right = right.getNext()
if n==1: # 删除末尾节点
left.setNext(None)
else: # 若删除中间节点
left.setNext(left.getNext().getNext())
return self.head
if __name__ == '__main__':
mylb = DeleteNNode()
mylb.add(9)
mylb.add(1)
mylb.add(5)
mylb.add(4)
mylb.delete_n_node(2)
print([ele for ele in mylb.show()])
总结
a. 删除链表节点只需注意: 头结点+中间节点+尾结点。三点即可。
b. 在进阶中,两个指针整体移动到末尾节点的判断语句是: while right.next() != None: 而不是 while right != None: 。