题目:
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
思路:
最初的想法是,递归,但是对链表的特性跟递归的使用还是不熟悉,一时间没有想到对应的实现。
这里推荐一个递归的基础思路学习:https://www.cnblogs.com/kubidemanong/p/10538799.html
方法一:
取出每层节点的val值添加到新的列表中,重新创建符合条件的链表结构,这个是没有思考的思路= = 、。
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
temp = []
while(1):
if head.next:
temp.append(head.val)
head = head.next
else:
temp.append(head.val)
break
if len(temp)==1:
return None
temp.pop(len(temp)-n)
res = ListNode(temp[0])
res_temp = res
for i in xrange(1,len(temp)):
res_temp.next = ListNode(temp[i])
res_temp = res_temp.next
return res
执行用时:12 ms, 在所有 Python 提交中击败了99.71%的用户
内存消耗:12.8 MB, 在所有 Python 提交中击败了9.09%的用户
方法二:
递归思路,递归的三要素,明确函数功能,找到终止条件,找到等价关系。
这里前后各print了一下head和head.next, 你就会发现递归真有意思,这个题目倒序删除的要求简直就是为递归量身定做。
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
global i
if head is None:
i=0
return None
print head,head.next
head.next = self.removeNthFromEnd(head.next,n)
i+=1
print \'******\'
print i,n,head,head.next
return head.next if i==n else head #i=n时,head=head.next.next删除指定n
\'\'\'
预期结果
[1,2,3,5]
ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}}}} ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}}}
ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}}} ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}}
ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}} ListNode{val: 4, next: ListNode{val: 5, next: None}}
ListNode{val: 4, next: ListNode{val: 5, next: None}} ListNode{val: 5, next: None}
ListNode{val: 5, next: None} None
******
1 2 ListNode{val: 5, next: None} None
******
2 2 ListNode{val: 4, next: ListNode{val: 5, next: None}} ListNode{val: 5, next: None}
******
3 2 ListNode{val: 3, next: ListNode{val: 5, next: None}} ListNode{val: 5, next: None}
******
4 2 ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 5, next: None}}} ListNode{val: 3, next: ListNode{val: 5, next: None}}
******
5 2 ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 5, next: None}}}} ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 5, next: None}}}
\'\'\'
方法三:
一次遍历(来自题解王尼玛大大的思路分享).
当链表总长度是k时,如果要删除倒数第n个节点(假设n小于k),那么首先要找到第k-n个节点,k-n这个节点就是要删除的节点的前一个节点。
当找到k-n这个节点就好办了,直接将k-n的next指针指向下下一个节点即可。
我们需要两个指针a和b。
b指针先走n步,接着a和b指针同时往前走,当b指针走到链表末尾时,a指针就正好走到要删除的节点的前一个位置了,最后a节点的next指针指向下下一个节点,就可以完成删除操作了。
思路很清晰啊有木有,真棒... 顺便diss下自己
以上是关于LeetCode 19.删除链表的倒数第N个节点的主要内容,如果未能解决你的问题,请参考以下文章