IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【代码随想录算法训练营】D4 24.两两交换链表中的节点 19. 删除链表的倒数第N个节点 面试题02.07 链表相交 142. 环形链表Ⅱ -> 正文阅读

[数据结构与算法]【代码随想录算法训练营】D4 24.两两交换链表中的节点 19. 删除链表的倒数第N个节点 面试题02.07 链表相交 142. 环形链表Ⅱ

今日题目:

  • 24.两两交换链表中的节点
  • 19. 删除链表的倒数第N个节点
  • 面试题02.07 链表相交
  • 142. 环形链表Ⅱ

解题思想:

  1. 虚拟头结点

在24. 两两交换链表中的节点此题中,同样需要设置虚拟头结点,它指向的是需要进行交换的两个节点的前一个位置。这样就可以用它来控制两个节点的交换。
需要注意循环的结束条件:因为cur指针指向的是两个交换节点的前一个节点位置,所以当cur指针后面没有节点,或者只有一个节点,都是循环停止的条件,即!cur.next || !cur.next.next

  1. 删除链表节点

第19题删除链表的倒数第n个节点,此题的关键点是如何找到要删除的节点的前一个位置。删除第n个节点,操作指针一定要指在第n-1个节点位置上
利用双指针,快指针先走n步,然后快慢指针同时走,直到快指针指向null停止,此时慢指针停在的位置就是倒数第n个节点,但是我们需要的是慢指针停在第n-1个节点,所以快指针应该在最开始多走一步,走n-1个位置。

  1. 链表相交

想要找出链表之间开始相交的位置,需要先计算出两条链表的长度,再让它们尾部对齐,再逐个对比节点所在的值是否相等。
题目不难,但是可以使用一些小技巧让代码更优雅:计算链表的这部分逻辑可以抽离出去,写一个函数专门用来计算链表长度;再者,为了使得代码逻辑不重复,可以让链表A永远是比较长的链表,如果不是的话就交换,这样操作链表对齐的时候只需要对A链表进行指针移动。

  1. 判断链表是否有环

使用快慢指针,分别定义fast和slow指针,从头结点触发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果fast和slow指针在中途相遇,则说明链表有环。
因为如果有环,fast指针必定先进入环中,如果fast指针与slow指针相遇,必定在环中相遇。

  1. 寻找环的入口

在这里插入图片描述
我们要求的是x,slow指针走过的节点数x+y
fast指针走过的节点数x+y+n(y+z) n为fast指针在环内走了n圈才遇到slow指针,(y+z)为一圈节点的个数
同时,fast指针走过的节点数= 2*slow指针走过的节点数(x+y)*2 = x+y+n(y+z)
两边消掉一个(x+y):x+y=n(y+z),因为要求的是x, x=n(y+z)-y,再将这个式子变形,得到x=(n-1)(y+z)+z
重点分析此等式,因为n是fast转的圈数。一定大于等于1,当n等于1的时候,得到等式x=z。不管n等于多少,相遇点都在环入口位置。
所以,计算环的开始位置,就是计算z,可以记录上次快慢指针的相交位置,当快慢指针相遇的时候,让其中一个回到头结点,然后同速前进,再次相遇即为环开始的位置


代码:

  • 24.两两交换链表中的节点
//迭代法
var swapPairs = function(head) {
    if(!head || !head.next) return head
    const dummyHead = new ListNode(0,head)
    let pre = dummyHead
    while(pre.next && pre.next.next) {
        let node1 = pre.next
        let node2 = pre.next.next

        pre.next = node2
        node1.next = node2.next
        node2.next = node1
        pre = node1
    }

    return dummyHead.next
};
//递归法
var swapPairs = function(head) {
    if(!head || !head.next) return head
    const newHead = head.next

    head.next = swapPairs(head.next.next)
    newHead.next = head 

    return newHead
};
  • 19 . 删除链表的倒数第N个节点
var removeNthFromEnd = function(head, n) {
    const dummyHead = new ListNode(0, head)
    let slow = fast = dummyHead
    while(n--) {
        fast = fast.next
    }
    //快指针再多走一步
    fast = fast.next
    while(fast){
        slow = slow.next
        fast = fast.next
    }
    //删除节点的操作
    slow.next = slow.next.next
    return dummyHead.next
};
  • 面试题02.07 链表相交
var getIntersectionNode = function(headA, headB) {
    let curA = headA
    let curB = headB
    let lenA = getListLen(headA)
    let lenB = getListLen(headB)

    if(lenA < lenB) {
        //注意这里需要加分号!
        [curA, curB] = [curB, curA];
        [lenA, lenB] = [lenB, lenA]
    }

    let i = lenA - lenB
    while(i--) {
        curA = curA.next
    }
    //注意这里是判断节点地址是否相同,不是节点的值
    while(curA && curA !== curB) {
        curA = curA.next
        curB = curB.next
    }

    return curA
};

var getListLen = function(head) {
    let len = 0
    let cur = head
    while(cur) {
        len++
        cur = cur.next
    }
    return len
}
  • 142 . 环形链表Ⅱ
var detectCycle = function(head) {
    //首先判断链表是否有环
    if(!head || !head.next) return null
    let slow = head.next
    let fast = head.next.next
    while(fast && fast.next && fast !== slow) {
        slow = slow.next
        fast = fast.next.next
    }
    if(!fast || !fast.next) return null

    //让slow指针从头开始,两个指针同速前进
    slow = head
    while(fast !== slow) {
        slow = slow.next
        fast = fast.next
    }
    return slow
};

总结:

真的好困啊啊啊啊啊明天继续

删除链表节点的关键是,操作要删除的链表的节点的上一个位置。删除倒数第n个节点,可以利用双指针的方式巧妙控制位置。
环形链表两个问题,一,判断是否有环,当快指针遇到了空,当然没有环。二,判断链表环的位置,利用数学公式推导,可以发现快慢指针相交位置到环入口处的距离,等于链表开始位置到环入口处的距离,所以可以在两快慢指针相交后,把慢指针放回头部,两节点同速移动,到下次相遇的位置就是环的入口位置。

这些方法要是我自己想真的很难想到,不得不说有些解题思路真是太妙了!!!终于追平进度啦~链表结束,哈希表我来咯

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:39:02  更:2022-10-22 21:46:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:51:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码