本文参考

出自LeetCode上的题库 —— 删除链表的倒数第n个结点,官方的双指针解法没有完全符合"只遍历一遍链表"的要求,本文给出另一种双指针解法

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/

删除倒数结点问题

给你一个链表,删除链表的倒数第 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]

解题思路

第一种解法,先遍历一遍原列表,记录链表长度,然后再遍历一遍就能够删除对应的结点

第二种解法利用双指针,我们"回文链表"(https://www.cnblogs.com/kuluo/p/15955593.html)中通过双指针找到中间节点(slow指针所在的位置),因此也能够计算链表的长度。获取到链表的长度后,根据倒数第n个结点是在slow指针前还是在slow指针后,决定是从head头节点开始找,还是从slow指针所指的结点开始找,相当于减少了一半的结点遍历过程

在这道题中,我们看到双指针不但能够使算法保持在$O(n)$的时间复杂度,也能将空间复杂度限制在常数级$O(1)$

双指针解法

class ListNode:

  def __init__(self, val=0, next=None):

    self.val = val

    self.next: ListNode = next
class Solution:

  def remove_Nth_from_end(self, head: ListNode, n: int) -> ListNode:

    cnt = 1

    slow = fast = head

    # 通过快慢指针获得链表长度 

    while fast.next and fast.next.next:

      cnt += 1

      slow = slow.next
      fast = fast.next.next

    # 计算链表长度 

    if fast.next is None:

      length = cnt * 2 - 1

    else:

      length = cnt * 2

    # 特殊情况 

    if n == length:

      return head.next

    # 链表的前半部分 
        # length = 5, n = 2, step = 5 - 2 - 3 + 1 = 1

    if
n > length / 2:

      step = length - n
      curr = pre = head

    # 链表的后半部分 

    else:

      step = length - n - cnt + 1

      curr = pre = slow

    # 获得步长后移动到特定位置并删除指针 

    for i in range(step):

      pre = curr
      curr = curr.next
    curr = curr.next
    pre.next = curr

    return head

最新文章

  1. MATLAB 成对T检验(paired-ttest)
  2. “div+css”下拉菜单
  3. Django的views中的request
  4. BW知识问答锦集2
  5. Spring知识点总结大全(1)
  6. Struts2自定义类型转换,和处理类型转换错误
  7. PHP 每天的总结(1)
  8. 游标、动态sql、异常
  9. 华东交通大学2016年ACM“双基”程序设计竞赛 1004
  10. 13.首次安装CY7C68013A驱动失败记(结果竟然是这样)
  11. DataGridView控件-学习笔记总结
  12. Java语言----三种循环语句的区别
  13. ARM--存储管理器
  14. OpenCart 之registry功用
  15. asp.net中后台javaScrip的使用
  16. RunTime 应用实例–关于埋点的思考
  17. 基于karma和jasmine的Angularjs 单元测试
  18. ash
  19. netstat 查看连接数
  20. c++(单向链表)

热门文章

  1. C#foreach 本质( 鸭子类型遍历)
  2. C# typeof() 和object.GetType() 、Type..GetType()使用和区别
  3. java this 用法详解
  4. KTL 一个支持C++14编辑公式的K线技术工具平台 - 第四版,稳定支持Qt5编程,zqt5语法升级,MA函数提升性能1000%,更多公式算法的内置优化实现。
  5. 《手把手教你》系列技巧篇(七十一)-java+ selenium自动化测试-自定义类解决元素同步问题(详解教程)
  6. JZ-038-二叉树的深度
  7. git--撤销添加&放弃修改&代码冲突
  8. xor加密的python实现
  9. 如何使用 VS Code 远程连接矩池云主机
  10. 矩池云 | 教你如何使用GAN为口袋妖怪上色