LeetCode 19.删除链表的倒数第N个节点

Posted 萧蔷ink

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 19.删除链表的倒数第N个节点相关的知识,希望对你有一定的参考价值。

题目:


给定一个链表,删除链表的倒数第 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个节点的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 19.删除链表的倒数第N个节点

leetcode 19. 删除链表的倒数第N个节点

leetcode 19. 删除链表的倒数第N个节点

LeetCode19----删除链表的倒数第N个节点

leetcode 19 删除链表的倒数第N个节点

LeetCode 19——删除链表的倒数第 N 个节点