首页 > 编程语言 >代码随想录算法训练营第四天(LeetCode24.两两交换链表中的节点;LeetCode10.删除链表的倒数第N个节点;LeetCode面试题02.07.链表相交;LeetCode142.环形链表Ⅱ)

代码随想录算法训练营第四天(LeetCode24.两两交换链表中的节点;LeetCode10.删除链表的倒数第N个节点;LeetCode面试题02.07.链表相交;LeetCode142.环形链表Ⅱ)

时间:2024-11-12 11:14:32浏览次数:3  
标签:slow ListNode 随想录 fast next 链表 节点

LeetCode 24. 两两交换链表中的节点

题目链接:两两交换链表中的节点题目链接

思路

这道题其实就是一个模拟题,要求每次交换链表中两个相邻的节点(1、2 节点互换;3、4 节点互换;2、3 节点不互换,意思就是交换过的节点不参与后续的交换了),同时只能进行节点交换,不能进行值交换。主要考察的就是指针变换的先后顺序。为了确保链表中的头指针和其他指针的操作模式相同,所以添加了虚拟头节点。所以每次 cur 先指向需要交换的两个节点的前一个节点,将这三个节点记作 0、1、2。那么具体的指向过程就是 0 先指向 2,1 指向 2 的后一个节点,2 指向 1,即完成了交换过程。

代码

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummyhead=new ListNode(0);
        dummyhead.next=head;
        ListNode cur=dummyhead;
        while(cur.next!=null&&cur.next.next!=null)
        {
            ListNode temp1=cur.next;
            ListNode temp2=cur.next.next;
            cur.next=temp2;
            temp1.next=temp2.next;
            temp2.next=temp1;
            cur=cur.next.next;
        }
        return dummyhead.next;
    }
}

时间复杂度:O (n) 遍历了整个链表
空间复杂度:O (1) 没有创建新的链表

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

题目链接:删除链表的倒数第N个节点

思路

删除链表的倒数第 N 个节点需要我们将一个指针指向倒数第 N 个节点的前一个节点才可以完成删除第 N 个节点的操作。我们可以使用双指针的做法来解决本题,一个指针 fast 先向前走 N 次,然后再让 fast 和 slow 指针一起走,走到 fast.next!=null 为止,此时 slow 指针指向要删除的节点的前一个节点,此时我们执行删除操作就可以了。

代码

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummyhead=new ListNode(0);
        dummyhead.next=head;
        ListNode fast=dummyhead;
        ListNode slow=dummyhead;
        for(int i=1;i<=n;i++)
            fast=fast.next;
        while(fast.next!=null)
        {
            fast=fast.next;
            slow=slow.next;
        }
        slow.next=slow.next.next;
        return dummyhead.next;
    }
}

LeetCode面试题02.07.链表相交

题目链接:链表相交题目链接

思路

该题目给定两个单链表,让我们求两个单链表相交的起始节点。因为两个单链表相交后的那部分长度是相同的,但是未相交前的长度不一定相同,所以我们需要先求解两个单链表的长度,然后将两个单链表的长度缩减为相同长,然后再比较两个单链表是否有节点相同部分,如果有的话,一开始的节点相同部分就是两个单链表的相交部分。

代码

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA=headA;
        ListNode curB=headB;
        int lenA=0;
        int lenB=0;
        while(curA!=null)
        {
            curA=curA.next;
            lenA++;
        }
        while(curB!=null)
        {
            curB=curB.next;
            lenB++;
        }
        curA=headA;
        curB=headB;
        if(lenA>=lenB)
        {
            int gap=lenA-lenB;
            while(gap-->0)
                curA=curA.next;
            while(curA!=null)
            {
                if(curA==curB)
                    return curA;
                curA=curA.next;
                curB=curB.next;
            }
        }
        else
        {
            int gap=lenB-lenA;
            while(gap-->0)
                curB=curB.next;
            while(curB !=null)
            {
                if(curB==curA)
                    return curB;
                curB=curB.next;
                curA=curA.next;
            }
        }
        return null;
    }
}

LeetCode142.环形链表Ⅱ

题目链接:环形链表Ⅱ题目链接

思路

首先我们设计一个快指针 fast,然后设计一个慢指针 slow,每次让 fast 走两步,让 slow 走一步,如果出现了 fast==slow ,那么说明链表中一定有环。那么为什么 fast 和 slow 一定可以相遇呢?因为 fast 和 slow 相遇,一定是 fast 又追上了 slow,那么相对于 slow 来说,fast 每次走一步,所以是不会跳过 slow 的,而是一定会遇到的。那么我们设头节点到环形链表的入口的距离为 x,环形链表的入口到 fast 和 slow 相遇的位置的距离为 y,fast 和 slow 相遇的位置到环形链表的入口的距离为 z。Fast 和 slow 相遇时,slow 走的距离为 x+y,fast 走的距离为 x+y+n (y+z),因为 fast 走的距离是 slow 走的距离的两倍,所以等式 2 (x+y)=x+y+n (y+z) 成立,将等式优化一下,可以得到 x=(n-1)(y+z)+z,n 是一定大于等于 1 的,因为 fast 在追上 slow 时一定会已经走了一圈了。假设 n=1,可以得到 x=z。说明从头节点走到环形链表的入口和从相遇节点走到环形链表的入口的距离时相等的,如果 n>1,则说明从头节点走到环形链表的入口和从相遇节点走到环形链表的入口+在环里走的圈数的距离时相等的,那么当我们找到 fast 和 slow 相遇的地方时,我们只需要设计两个指针,一个指针从头节点开始走,每次走一步,一个指针从相遇节点开始走,每次走一步,当这两个节点相遇时,所在的位置就是环形链表的入口节点。

代码

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null)
        {
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast)
            {
                ListNode index1=slow;
                ListNode index2=head;
                while(index1!=index2)
                {
                    index1=index1.next;
                    index2=index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}

标签:slow,ListNode,随想录,fast,next,链表,节点
From: https://blog.csdn.net/qq_51597940/article/details/143707411

相关文章

  • 【初阶数据结构与算法】线性表之链表的分类以及双链表的定义与实现
    文章目录一、链表的分类二、双链表的实现1.双链表结构的定义2.双链表的初始化和销毁初始化函数1初始化函数2销毁函数3.双链表的打印以及节点的申请打印函数节点的申请4.双链表的头插和尾插头插函数尾插函数5.双链表的查找和判空查找函数判空函数6.双链表的头删和尾......
  • Mysql篇-Buffer Pool中的三大链表
    为什么要有BufferPool?虽然说MySQL的数据是存储在磁盘里的,但是也不能每次都从磁盘里面读取数据,这样性能是极差的。要想提升查询性能,那就加个缓存。所以,当数据从磁盘中取出后,缓存内存中,下次查询同样的数据的时候,直接从内存中读取。为此,Innodb存储引擎设计了一个缓冲池(Buffer......
  • 计算二叉树(二叉链表)的带权路径长度
    方法1#include<bits/stdc++.h>#defineintlonglong#definemod998244353usingnamespacestd;usingpii=pair<int,int>;typedefstructBtnode{ intdata; structBtnode*lc,*rc; }*Btree,Btnode;//笔试这个可以放上面,但是真的写程序应该把getwpl放在g......
  • AcWing 1626:链表元素分类 ← 单链表
    【题目来源】https://www.acwing.com/problem/content/1628/【题目描述】给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而[0,K]区间内的元素都排在大于K的元素前面。但每一类内部元素的顺序是不能改变的。例如:给定链表为18→......
  • 企业生产环境-麒麟V10(ARM架构)操作系统部署Zookeeper单节点&高可用集群版
    前言:ZooKeeper是一个分布式协调服务,它为分布式应用提供一致性服务,是ApacheHadoop的子项目。它被设计为易于编程,同时具有高性能和高可靠性。ZooKeeper提供了一个简单的接口和一些基本的文件系统操作,使得开发者能够快速地构建分布式应用。以下是ZooKeeper的一些关键特性和概念:......
  • 代码随想录算法训练营第二十二天| leetcode77. 组合、leetcode216.组合总和III、leetc
    1leetcode77.组合题目链接:77.组合-力扣(LeetCode)文章链接:代码随想录视频链接:带你学透回溯算法-组合问题(对应力扣题目:77.组合)|回溯法精讲!_哔哩哔哩_bilibili思路:开始想循环,感觉行不通,然后看了视频,就嗯理解了一些感觉跟递归的思路确实差不多1.1回溯三部曲回溯的方法首......
  • 代码随想录算法训练营day43| 300.最长递增子序列 674. 最长连续递增序列 718. 最长
    学习资料:https://programmercarl.com/0300.最长上升子序列.html#算法公开课动态规划系列之子序列学习记录300.最长递增子序列(长度最少为1;dp[i]代表到i为止的最长子序列的长度;i的值根据i之前比如j的值来判断;每个地方都有可能获得最长长度)点击查看代码classSolution:def......
  • 代码随想录算法训练营第十一天 | 150. 逆波兰表达式求值+ 239. 滑动窗口最大值+347.前
    今天接着补上周末的栈与队列的part2,下午继续完成今天的任务。150.逆波兰表达式求值 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。注意:有效的算符为 '+'、'-'、'*' 和 '/' 。每个......
  • 代码随想录算法训练营第十天 | 232.用栈实现队列+225. 用队列实现栈+20. 有效的括号+1
    加入训练营有点晚,没跟上任务就开始有些偷懒没有真的认真开始,从第十天开始下决心认真完成每天任务还有博客记录学习过程。栈与队列理论基础首先是学习了栈和队列的理论基础,队列 先进先出,栈 先进后出。栈 以底层容器完成其所有的工作,且对外接口统一,有.push,.pop等,不提供......
  • 代码随想录——二叉树-12.平衡二叉树
    自顶向下递归(前序遍历)这种方法是一开始想到的,虽然ac了但是对于它的本质却不清不楚,不知道时间复杂度,不知道属于前序遍历。思路首先得到root节点的左右子树的深度(左右),若深度差绝对值大于1(中),则root为根的树不是平衡二叉树;否则继续递归root的左右子树,其左右子树都是平衡二叉树......