Python算法题集_删除链表的倒数第 N 个结点

 Python算法题集_删除链表的倒数第 N 个结点

  • 题19:删除链表的倒数第 N 个结点
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【二次遍历】
    • 2) 改进版一【快慢指针】
    • 3) 改进版二【列表裁剪】
  • 4. 最优算法

本文为Python算法题集之一的代码示例

题19:删除链表的倒数第 N 个结点

1. 示例说明

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

      示例 1:

      Python算法题集_删除链表的倒数第 N 个结点_第1张图片

      输入:head = [1,2,3,4,5], n = 2
      输出:[1,2,3,5]
      
      **示例 2:**
    
    

    输入:head = [1], n = 1
    输出:[]

    **示例 3:**
    
    

    输入:head = [1,2], n = 1
    输出:[1]

     
    
    **提示:**
    
    - 链表中结点的数目为 `sz`
    - `1 <= sz <= 30`
    - `0 <= Node.val <= 100`
    - `1 <= n <= sz`
    
     
    
    **进阶:**你能尝试使用一趟扫描实现吗?
    

2. 题目解析

- 题意分解

  1. 本题为删除链表中间的节点
  2. 本题的主要计算是链表遍历
  3. 基本的解法是循环,链表1读一遍,链表2读一遍,所以基本的时间算法复杂度为O(m)

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 标准发放是遍历一遍求链表长度,在走到要删除的节点执行删除操作

    2. 使用快慢指针的方式,可以一次扫描完成

    3. 可以用列表结构进行节点删除【注意如果要删除多个节点,列表是最优选择】


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题很难超时,本地化超时测试用例自己生成,详见【最优算法章节】

3. 代码展开

1) 标准求解【二次遍历】

第一次遍历获得链表长度,第二次遍历完成删除

半生不熟,超过50%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 @staticmethod
 def removeNthFromEnd_base(head, n):
     ilength, tmpNode = 0, head
     while tmpNode:
         ilength += 1
         tmpNode = tmpNode.next
     iPos, target = 0, ilength - n - 1
     if target == -1:
         return head.next
     tmpNode = head
     while iPos != target:
         iPos += 1
         tmpNode = tmpNode.next
     tmpNode.next = tmpNode.next.next
     return head

result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_base, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 removeNthFromEnd_base 的运行时间为 18.01 ms;内存使用量为 4.00 KB 执行结果 = 0

2) 改进版一【快慢指针】

将快慢指针距离调整为n,然后一次遍历完成

出类拔萃,超过89%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 @staticmethod
 def removeNthFromEnd_ext1(head, n):
     slownode, fastnode = head, head
     for iIdx in range(n):
         fastnode = fastnode.next
     if not fastnode:
         return head.next
     while fastnode.next:
         slownode = slownode.next
         fastnode = fastnode.next
     slownode.next = slownode.next.next
     return head

result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_ext1, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 removeNthFromEnd_ext1 的运行时间为 10.00 ms;内存使用量为 0.00 KB 执行结果 = 0

3) 改进版二【列表裁剪】

将链表转换为数组,再裁剪链表

出类拔萃,超过89%Python算法题集_删除链表的倒数第 N 个结点_第2张图片

import CheckFuncPerf as cfp

class Solution:
 @staticmethod
 def removeNthFromEnd_ext2(head, n):
     list_Node = []
     tmpNode = head
     while tmpNode:
         list_Node.append(tmpNode)
         tmpNode = tmpNode.next
     if len(list_Node) < 1:
         return head
     if len(list_Node) == 1:
         return None
     if n == 1:
         list_Node[-n - 1].next = None
     elif n == len(list_Node):
         head = head.next
     else:
         list_Node[-n-1].next = list_Node[-n+1]
     return head

result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_ext2, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 removeNthFromEnd_ext2 的运行时间为 17.01 ms;内存使用量为 904.00 KB 执行结果 = 0

4. 最优算法

根据本地日志分析,最优算法为第2种removeNthFromEnd_ext1

nums = [ x for x in range(200000)]
def generateOneLinkedList(data):
    head = ListNode()
    current_node = head
    for num in data:
        new_node = ListNode(num)
        current_node.next = new_node
        current_node = new_node
    return head.next
ahead = generateOneLinkedList(nums)
result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_base, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 算法本地速度实测比较
函数 removeNthFromEnd_base 的运行时间为 18.01 ms;内存使用量为 4.00 KB 执行结果 = 0
函数 removeNthFromEnd_ext1 的运行时间为 10.00 ms;内存使用量为 0.00 KB 执行结果 = 0
函数 removeNthFromEnd_ext2 的运行时间为 17.01 ms;内存使用量为 904.00 KB 执行结果 = 0

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

你可能感兴趣的:(Python,python,算法,链表,leetcode,链表删除)