LeetCode题目(Python实现):删除链表的倒数第N个节点

文章目录

  • 题目
    • 想法一:哈希表
      • 算法实现
      • 执行结果
      • 复杂度分析
    • 两次遍历
      • 算法实现
      • 执行结果
      • 复杂度分析
    • 一次遍历
      • 算法实现
      • 执行结果
      • 复杂度分析
    • 小结

题目

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例 :

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明

给定的 n 保证是有效的。

进阶

你能尝试使用一趟扫描实现吗?

想法一:哈希表

算法实现

def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
    dic = {}
    cur = head
    i = 0
    while cur:
        dic.update({i: cur})
        cur = cur.next
        i += 1
    if i == n:
        return head.next
    elif n == 1:
        dic[i - n - 1].next = None
    else:
        dic[i - n - 1].next = dic[i - n + 1]
    return head

执行结果

执行结果 : 通过
执行用时 : 36 ms, 在所有 Python3 提交中击败了70.62%的用户
内存消耗 : 13.5 MB, 在所有 Python3 提交中击败了11.85%的用户
LeetCode题目(Python实现):删除链表的倒数第N个节点_第1张图片

复杂度分析

  • 时间复杂度:O(n),
    我们一个链表所有节点。

  • 空间复杂度:O(n)
    需要额外的n个节点来储存链表每一个节点。

两次遍历

算法实现

def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
    if not head or n <= 0:
        return head
    # 增加一个特殊节点,方便边界处理
    p = ListNode(-1)
    p.next, a, b, k = head, p, p, 0
    # 第一次遍历,计算链表总长度
    while a.next:
        a, k = a.next, k + 1
    # 如果链表总长度小于n,那就直接返回
    if k < n:
        return head
    # 计算第二次遍历多少个节点
    num = k - n
    # 第二次遍历,找到要删除节点的前一个节点
    while num > 0:
        b, num = b.next, num - 1
    # 删除节点,并返回
    b.next = b.next.next
    return p.next

执行结果

LeetCode题目(Python实现):删除链表的倒数第N个节点_第2张图片

复杂度分析

  • 时间复杂度:O(n),
    该算法对列表进行了两次遍历。

  • 空间复杂度:O(1)

一次遍历

算法实现

def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
    # 增加一个特殊节点方便边界判断
    p = ListNode(-1)
    p.next, a, b = head, p, p
    # 第一个循环,b指针先往前走n步
    while n > 0 and b:
        b, n = b.next, n - 1
    # 假设整个链表长5,n是10,那么第一次遍历完后b就等用于空了
    # 于是后面的判断就不用做了,直接返回
    if not b:
        return head
    # 第二次,b指针走到链表最后,a指针也跟着走
    # 当遍历结束时,a指针就指向要删除的节点的前一个位置
    while b.next:
        a, b = a.next, b.next
    # 删除节点并返回
    a.next = a.next.next
    return p.next

执行结果

LeetCode题目(Python实现):删除链表的倒数第N个节点_第3张图片

复杂度分析

  • 时间复杂度:O(n),
    该算法对列表进行了一次遍历。

  • 空间复杂度:O(1)

小结

先按照自己的想法设计,说道一次遍历想到的首先是哈希表,储存节点,然后查找,速度还算可以。

之后看了两次遍历,即先找到链表的长度,再重新遍历去删除。

一次遍历的另一种方式双指针很精妙,学到了=。=

你可能感兴趣的:(LeetCode题目)