代码随想录算法训练营day4 | 链表(2)

news2024/11/16 15:42:33

一、LeetCode 24 两两交换链表中的节点

题目链接:24.两两交换链表中的节点icon-default.png?t=N7T8https://leetcode.cn/problems/swap-nodes-in-pairs/

思路:设置快慢指针,暂存节点逐对进行交换。

代码优化前:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        //头部结点交换
        ListNode cur = head;         //cur存储节点1
        ListNode now = cur.next;    //now存储节点2
        ListNode temp_n = now;       //暂存节点2
        ListNode temp_c = now.next;  //暂存下一轮的节点_1
        now.next = cur;              //节点2 → 节点1
        head = now;                  //head - 节点2
        now = cur;                   //now - 节点1
        cur.next = temp_c;           //节点1 → 节点_1
        cur = temp_c;                //cur - 节点_1
        //while循环中逻辑与上同
        while(cur != null && cur.next != null){
            temp_n = now;
            now = cur.next;
            temp_n.next = now;
            temp_c = now.next;
            now.next = cur;
            now = cur;
            cur.next = temp_c;
            cur = temp_c;
        }
        return head;
    }
}

代码优化后:

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

题目链接:19.删除链表的倒数第N个节点icon-default.png?t=N7T8https://leetcode.cn/problems/remove-nth-node-from-end-of-list/

思路:考虑使用快慢指针。先处理特殊情况(单节点链表或删除头结点);快慢指针同时后移、找到要删除节点的前一个节点做删除处理。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        //单个元素
        if(head.next == null){
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        //删除倒数第n个节点、快指针先行n步
        while(fast != null && n > 0){
            fast = fast.next;
            n--;
        }
        //fast先行n步到链表末尾,说明要删除第一个节点
        if(fast == null){
            return head.next;
        }
        //slow指针与fast指针同时后移,找到要删除节点的前一个节点
        //(所以是fast.next!=null 而不是fast != null)
        while(fast.next != null){
            slow = slow.next;
            fast = fast.next;
        }
        //删除节点
        slow.next = slow.next.next;
        return head;
    }
}

 三、LeetCode 面试题 02 07 链表相交

题目链接:面试题02.07.链表相交icon-default.png?t=N7T8https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/

思路:

计算链表A、B长度、并把指针移动到链表结尾;利用链表A、B长度差,调整较长链表的遍历指针到剩余长度与较短链表的长度相同的位置;A、B遍历指针同步后移,找到相交位置。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode index_a = headA;
        ListNode index_b = headB;
        //处理链表A、B为空的情况
        if(index_a == null || index_b == null){
            return null;
        }
        //计算链表A、B长度、并把指针移动到链表结尾
        int len_a = 1,len_b = 1;
        while(index_a != null && index_a.next != null){
            index_a = index_a.next;
            len_a++;
        }
        while(index_b != null && index_b.next != null){
            index_b = index_b.next;
            len_b++;
        }
        //结尾指针指向的节点不同,说明不相交
        if(index_a != index_b){
            return null;
        }
        //指针回到头部
        index_a = headA;
        index_b = headB;
        //利用链表A、B长度差,调整较长链表的遍历指针到剩余长度与较短链表的长度相同的位置
        //A、B遍历指针同步后移,找到相交位置
        if(len_a > len_b){
            int num = len_a - len_b;
            while(num > 0){
                index_a = index_a.next;
                num--;
            }
            while(index_a != index_b){
                index_a = index_a.next;
                index_b = index_b.next;
            }
        }else{
            int num = len_b - len_a;
            while(num > 0){
                index_b = index_b.next;
                num--;
            }
            while(index_a != index_b){
                index_a = index_a.next;
                index_b = index_b.next;
            }
        }
        return index_a;
    }
}

 四、LeetCode 142 环形链表II

题目链接:142.环形链表IIicon-default.png?t=N7T8https://leetcode.cn/problems/linked-list-cycle-ii/description/

思路:

        先判断是否有环:设置快慢指针fast、slow。在每个循环中,fast后移2次、slow后移1次,作图可知,若链表有环,则fast与slow必然能够相遇且必定在环内相遇。

        再确定环入口:设head到环入口的长度为x,环入口到fast、slow相遇点的长度为y,相遇点到换入口的长度为z,fast在环内转了n圈才遇到slow;又因为fast的移动距离是slow的2倍,则可列: x+y+n*(y+z) = 2*(x+y) → x = (n-1)*(y+z)+z。

        当n = 1时,x = z,设置指针index_1 = head,index_2 = slow/fast(即相遇位置),易知index_1与index_2以相同的速度后移再相遇的位置即为环入口。

示意图:

代码如下:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            //fast指针移速是slow指针的2倍
            fast = fast.next.next;
            slow = slow.next;
            //fast与slow相遇
            if(slow == fast){
                ListNode index_1 = head;
                ListNode index_2 = slow;
                //由思路中的数学分析进行同步后移操作
                while(index_1 != index_2){
                    index_1 = index_1.next;
                    index_2 = index_2.next;
                }
                return index_1;
            }
        }
        //fast最终指向null,链表无环
        return null;
    }
}

五、今日小结

        链表知识果然难呜呜呜,好在坚持写完了~ 24、19两题有待优化,142不熟练过几天需要回顾。最近休息不太好很影响效率和状态,明天出门运动、调整作息,加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1415198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

总结和考试

总结和考试 1. 代码规范1.1 名称1.2 注释1.3 todo1.4 条件嵌套1.5 简单逻辑先处理1.6 循环1.7 变量和值 2.知识补充2.1 pass2.2 is 比较2.3 位运算 3.阶段总结4.考试题 1. 代码规范 程序员写代码是有规范的,不只是实现功能而已。 1.1 名称 在Python开发过程中会创…

EndNote20 添加GBT7714文献格式

GBT 7714格式是中国国家标准《文后参考文献著录规则》的规定,用于指导学术论文、期刊文章等文献的参考文献著录。GBT 7714标准规定了参考文献的格式、内容和著录要求,以确保文献的一致性和标准化。 在EndNote 20中,若需要按照GBT 7714格式在W…

JavaScript 之 作用域变量提升闭包

一、JavaScript 代码的执行 浏览器内核是由两部分组成的,以 webkit 为例 WebCore:负责HTML解析、布局、渲染等等相关的工作JavaScriptCore:解析、执行 JavaScript 代码 另外一个强大的 JavaScript 引擎就是 V8 引擎 二、深入 V8 引擎原理 …

Django介绍

一、介绍 Django是Python语言中的一个Web框架,Python语言中主流的web框架有Django、Tornado、Flask 等多种 优势:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等功能,是一个全能型框架,拥有自己的Admin数据管理后台,第三方工具齐全,性能折中 缺点:…

用ChatGPT写申请文书写进常春藤联盟?

一年前,ChatGPT 的发布引发了教育工作者的恐慌。现在,各大学正值大学申请季,担心学生会利用人工智能工具伪造入学论文。但是,聊天机器人创作的论文足以骗过大学招生顾问吗? ChatGPT简介 ChatGPT,全称聊天生…

C++:引用

目录 概念: 引用的使用格式: 引用特性: 常引用 使用场景: 1、做参数 二级指针时的取别名 一级指针取别名 一般函数取别名 2、做返回值 函数返回值的原理: 引用的返回值使用: 引用和指针的对比&…

基于 SpringBoot+Vue 的免税商品商城系统的研究与实现

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

免费电视TV盒子软件,好用的免费电视盒子软件大全,免费电视盒子APP大全,2024最新整理

1、TVbox下载地址、影视接口、配置教程 下载地址 TVbox TVbox可用接口地址合集 注:接口均来源于互联网收集分享!所有接口都是经过测试的,如果出现加载失败等情况,可能是因为接口针对的盒子有兼容问题,可以多试试几…

(七)springboot实战——springboot3集成R2DBC实现webflux响应式编程服务案例

前言 本节主要内容是关于使用新版springboot3集成响应式数据库R2DBC,完成响应式web服务案例。需要注意的是,此次项目使用的JDK版本是JDK17,springboot版本使用3.2.2版本,数据库使用关系型数据库mysql。WebFlux 是一个基于响应式编程模型的框…

redis过期事件监听、可以做延时任务 第二篇(简单)

在使用redis时,所有的key都要设置过期时间,过期之后,redis就会把对应的key清除掉。 此方法可以监听redis的key失效,在失效时做一些逻辑处理 redis过期监听 不像mq有保证 不推荐用来弄需要有保证的业务 现象: redis …

P1045 [NOIP2003 普及组] 麦森数题解

题目 形如的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P3021377,它有909526位。麦森数有许多重要应用,它与…

Linux版本下载Centos操作

目录 一、Centos7 二、下载Centos7镜像 三、下载Centos7 买了个硬件安装裸机(一堆硬件) 把安装盘放到虚拟机里面,给机器加电 配置设置 ​编辑 网络配置 开启网络功能 四、安装linux客户端 Xshell是什么 Xshell使用(连接…

GLog开源库使用

Glog地址:https://github.com/google/glog 官方文档:http://google-glog.googlecode.com/svn/trunk/doc/glog.html 1.利用CMake进行编译,生成VS解决方案 (1)在glog-master文件夹内新建一个build文件夹,用…

Java笔记 --- 二、Stream流

二、Stream流 结合Lambda表达式,简化集合、数组的操作 获取Stream流对象 单列集合获取Stream流 双列集合获取Stream流 数组获取Stream流 一堆零散的数据获取Stream流 Stream流的静态方法of的形参是一个可变参数,可以传递零散数据,也可以传递…

Scrapy IP()类 编程指南(基础)

Scrapy IP()类 编程指南(基础) IP简介 工欲善其事,必先利其器,在聊Scapy IP类时,我们先要了解IP是什么。 IP指的是Internet Protocol(互联网协议)的数据包。Internet Protocol是互联网上用于在…

超简单的正则表达式从入门到精通

正则表达式,又称规则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 概念 正则表达式是对字…

使用Promethues+Grafana监控Elasticsearch

PromethuesGrafana监控Elasticsearch 监控选用说明指标上报流程说明实现监控的步骤搭建elasticsearch-exporter服务搭建promethues和grafana服务 监控选用说明 虽然用Kibana来监控ES,能展示一些关键指标,但ES本身收集的指标并不全面,还需要在…

Qt : Style Sheet

When a style sheet is active, the QStyle returned by QWidget::style() is a wrapper “style sheet” style, not the platform-specific style. The wrapper style ensures that any active style sheet is respected and otherwise forwards the drawing operations to t…

Centos9使用chrony服务同步时间

安装chrony命令 Centos9里是预安装的,没有安装的话执行以下命令: yum install -y chronyCentos9 时间同步要使用chrony命令,ntp命令没有了 查看状态 #启用chronyd服务 systemctl enable chronyd#重启chronyd服务 systemctl restart chron…

【Docker】nacos集群搭建Nginx负载均衡

目录 一、mysql安装与基操 1.1 数据准备 1.2 创建mysql与数据表 二、Nacos集群部署 2.1 创建nacos及配置 2.2 创建Nginx容器 一、mysql安装与基操 1.1 数据准备 拉取mysql docker pull mysql:5.7(版本) 定义挂载目录 mkdir -p /mysql/{conf,data,script} 配置my.c…