力扣Hot100刷题日常(链表篇上)

news2025/1/18 10:50:21

相交链表

 题目分析:

暴力解法:

  1. 计算链表的长度: 首先我们需要知道链表 A 和链表 B 的长度。因为在开始比较两个链表是否相交之前,我们需要确保它们有相同的起始点。从长度上来说,两个链表的交点一定会出现在它们后续部分的某个地方。如果两个链表的长度不同,那么我们可以通过调整链表的头节点来使它们有相同的比较起点。

  2. 对齐链表的起始位置: 假设链表 A 比链表 B 长 len1 - len2 个节点,那么我们可以让链表 A 从第 len1 - len2 个节点开始遍历;如果链表 B 比链表 A 长,那么我们让链表 B 从第 len2 - len1 个节点开始遍历。这样我们就确保了两个链表的后续部分从相同的节点开始比较。

  3. 同时遍历两个链表: 在对齐了起始位置之后,我们就可以同步地遍历两个链表。如果两个链表在某个节点相遇,那么这个节点就是它们的交点。如果遍历结束后还没有相遇,就说明两个链表没有交点。

/**
 * 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 cur1 = headA;
        ListNode cur2 = headB;
        int len1 = 0, len2 = 0;
        while (cur1 != null) {
            len1++;
            cur1 = cur1.next;
        }
        while (cur2 != null) {
            len2++;
            cur2 = cur2.next;
        }
        int len = len1-len2;
        if(len < 0) {
            ListNode tmp = headA;
            headA = headB;
            headB = tmp;
            len = len2 - len1;
        }
        while(len != 0) {
            headA = headA.next;
            len--;
        }
        while(headA != null && headB!=null) {
            if(headA == headB) {
                return headA;
            }
            headA = headA.next;
            headB = headB.next;
        }
        return null;
    }
}

二.更优解

  • 假设两个链表 A 和 B 的长度分别为 m 和 n,它们有交点时,交点之后的部分是相同的。
  • 双指针通过遍历两个链表,保证它们在遍历完各自链表后会同步开始从对方链表的头节点开始走。这样,两指针最终会在交点相遇。假如没有交点,它们会同时到达 null
  • M+N = N+M
  • 即使双方没有交点,最后也都返回了null
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode cur1 = headA;
        ListNode cur2 = headB;
        while(cur1 != cur2 ) {
           cur1 = cur1 != null ? cur1.next : headB;
           cur2 = cur2 != null ? cur2.next : headA;
        }
        return cur1;
    }
}


反转链表

 

反转的过程可以分为以下几个步骤:

  1. 保存下一个节点next(防止丢失链表的剩余部分)。
  2. 改变当前节点的head 指针,指向cur。
  3. 更新 cur,表示反转后的链表的当前节点。
  4. 更新head,指向next
  5. 继续遍历原链表,直到链表遍历完。
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null) {
            return null;
        }
        ListNode cur = null;
        while(head != null) {
            ListNode next= head.next;
            head.next = cur;
            cur = head;
            head = next;
        }
        return cur;
    }
}

 回文链表

 

 


class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head == null) {
            return true;
        }
        ListNode fast = head;
        ListNode slow = head;
        //1.找到中间节点
        while(fast !=null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        //2.翻转后半部分链表 从slow开始
        ListNode cur = null;
        while(slow != null) {
            ListNode next = slow.next;
            slow.next = cur;
            cur = slow;
            slow = next;
        }

        //3.从head  和 cur位置进行遍历
        while(cur != null) {
            if(head.val != cur.val) {
               return false;
            }else {
                head = head.next;
                cur = cur.next;
            }
        }
        return true;

    }
}

 环形链表

 

判断是否有环,执行一个快慢指针

当一个慢指针走一步,快指针走俩步,在一个圈里面,快指针将一定能追上慢指针 

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {

            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                return true;
            }
        }
        return false;
    }
}

环形链表 II

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

 合并两个有序链表

初始化: 伪头节点 dum ,节点 cur 指向 dum 。
循环合并: 当 l1 或 l2 为空时跳出。

        当 l1 .val<l 2 .val 时: cur 的后继节点指定为 l1,并 l1向前走一步。

        当 l1 .val≥l 2 .val 时: cur 的后继节点指定为 l2 ,并 l2 向前走一步 。

        节点 cur 向前走一步,即 cur=cur.next 。

合并剩余尾部: 跳出时有两种情况,即 l1为空 或 l2为空。

        若 l1=null : 将 l1添加至节点 cur 之后。

        否则: 将 l2添加至节点 cur 之后。
返回值:合并链表在伪头节点 dum 之后,因此返回 dum.next 即可。

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode dum = new ListNode(-1);
        ListNode cur = dum ;
        while (list1 != null && list2 != null) {
            if (list1.val >= list2.val) {
                cur.next = list2;
                cur = list2;
                list2 = list2.next;
            } else {
                cur.next = list1;
                cur = list1;
                list1 = list1.next;
            }
        }
        if (list1 != null) {
            cur.next = list1;
        }
        if (list2 != null) {
            cur.next = list2;
        }
        return dum .next;
    }
}

递归方法: 

  • 终止条件:两条链表分别名为 l1 和 l2,当 l1 为空或 l2 为空时结束
  • 返回值:每一层调用都返回排序好的链表头
  • 本级递归内容:如果 l1 的 val 值更小,则将 l1.next 与排序好的链表头相接,l2 同理

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1 == null) return list2;
        if(list2 == null) return list1;
        if(list1.val < list2.val) {
            list1.next = mergeTwoLists(list1.next,list2);
            return list1;
        }else {
            list2.next = mergeTwoLists(list1,list2.next);
            return list2;
        }
    }
}

 两数相加

 

  1. 通过 l1 和 l2 按位相加,处理每个节点。
  2. 用 t 记录当前位的和,并处理进位(t % 10 存入当前节点,t / 10 作为进位传递到下一位)。
  3. 当所有节点处理完毕,并且没有进位时,结束循环。
  4. 返回结果链表。
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode newHead = new ListNode(-1);
        ListNode cur = newHead;
        int t = 0;
        while(l1 != null || l2 != null || t !=0 ) {
            if(l1 != null) {
                t += l1.val;
                l1 = l1.next;
            }
            if(l2 != null) {
                t+= l2.val;
                l2 = l2.next;
            }
            cur.next = new ListNode(t%10);
            cur = cur.next;
            t /=10;
        }
        return newHead.next;
    }
}

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

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

相关文章

MySQL数据库安全与管理

1、创建两个新用户U_student1和U_student2,密码分别为1234和5678 create user U_student1@localhost identified by 1234, U_student2@localhost identified by 5678; 2、创建两个新用户的详细信息保存在MySQL数据库的user表中 use mysql; select user, host, authentication…

【数据库】关系代数和SQL语句

一 对于教学数据库的三个基本表 学生S(S#,SNAME,AGE,SEX) 学习SC(S#,C#,GRADE) 课程(C#,CNAME,TEACHER) &#xff08;1&#xff09;试用关系代数表达式和SQL语句表示&#xff1a;检索WANG同学不学的课程号 select C# from C where C# not in(select C# from SCwhere S# in…

在做题中学习(79):最小K个数

解法&#xff1a;快速选择算法 说明&#xff1a;堆排序也是经典解决问题的算法&#xff0c;但时间复杂度为&#xff1a;O(NlogK)&#xff0c;K为k个元素 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章&#xff0c;分别学习&#xff1a;数组分三块&#…

uniapp页面不跳转问题!(使用uni.$u.route或者原生uni.navigateTo)页面跳转ios无效果(既不报错也不跳转页面)

1.问题描述: 通常使用点击事件来触发页面跳转都没问题,但是现在业务需求,在一个方法中自动去携带参数跳转到另外一个页面,android真机无问题,就ios一直无法跳转过去! 2.解决方法: 2.1 必须使用setTimeout来延迟跳转 2.2 setTimeout的延迟时间必须要大于300 不要问为什么…

基于 Spring Boot + Vue 的宠物领养系统设计与实现

引言 近年来&#xff0c;随着人们生活水平的提高&#xff0c;宠物逐渐成为许多家庭的重要成员。然而&#xff0c;宠物的流浪和弃养问题日益严重&#xff0c;这促使社会对宠物领养的需求不断增长。为解决宠物领养中信息不对称、领养流程复杂等问题&#xff0c;设计并实现一个基…

设计模式学习[10]---迪米特法则+外观模式

文章目录 前言1. 迪米特法则2. 外观模式2.1 原理阐述2.2 举例说明 总结 前言 之前有写到过 依赖倒置原则&#xff0c;这篇博客中涉及到的迪米特法则和外观模式更像是这个依赖倒置原则的一个拓展。 设计模式的原则嘛&#xff0c;总归还是高内聚低耦合&#xff0c;下面就来阐述…

GDPU Android移动应用 访问网络

接到网络&#xff0c;开启你的访问之旅。 WebView的简单使用 WebView的简单使用&#xff0c;创建一个部件&#xff0c;上面一个button,下面一个webview布满整个屏幕&#xff0c;设置Web View的属性&#xff0c;使其可以执行Javascript&#xff08;自己尝试设置其他属性&#xf…

【burp】burpsuite基础(八)

Burp Suite基础&#xff08;八&#xff09; 声明&#xff1a;该笔记为up主 泷羽的课程笔记&#xff0c;本节链接指路。 警告&#xff1a;本教程仅作学习用途&#xff0c;若有用于非法行为的&#xff0c;概不负责。 ip伪装 安装组件jython 下载好后&#xff0c;在burp中打开扩展…

使用 EasyExcel 提升 Excel 处理效率

目录 前言1. EasyExcel 的优点2. EasyExcel 的功能3. 在项目中使用 EasyExcel3.1 引入依赖3.2 实体类的定义与注解3.3 工具类方法的实现3.4 在 Controller 中使用 4. 总结5. 参考地址 前言 在日常开发中&#xff0c;Excel 文件的处理是不可避免的一项任务&#xff0c;特别是在…

Liunx 中篇

3.4 打包压缩命令 3.5 文本编辑命令 文本编辑的命令&#xff0c;主要包含两个: vi 和 vim&#xff0c;两个命令的用法 类似&#xff0c;我们课程中主要讲解vim的使用。 3.5.1 vi和vim介绍 作用: vi命令是Linux系统提供的一个文本编辑工具&#xff0c;可以对文 件内容进行编辑…

kali Linux 安装配置教程(图文详解)

目录 一、下载安装VMware二、下载kali镜像三、安装kali到虚拟机 一、下载安装VMware 点我查看 二、下载kali镜像 官网下载&#xff1a;https://www.kali.org/get-kali/#kali-platforms 演示下载的为下图左边的&#xff0c;实际我们直接下载右侧虚拟机的直接使用就行 右侧下…

Bootstrap-HTML(四)徽章与表格

Bootstrap-HTML&#xff08;四&#xff09;徽章与表格 前言一、Bootstrap5 徽章&#xff08;一&#xff09;徽章的作用及创建&#xff08;二&#xff09;胶囊徽章&#xff08;三&#xff09;元素内的徽章 二、Bootstrap5 表格&#xff08;一&#xff09;创建一个简单的表格&…

RabbitMQ介绍及安装

文章目录 一. MQ二. RabbitMQ三. RabbitMQ作用四. MQ产品对比五. 安装RabbitMQ1. 安装erlang2. 安装rabbitMQ3. 安装RabbitMQ管理界⾯4. 启动服务5. 访问界面6. 添加管理员用户7. 重新登录 一. MQ MQ( Message queue ), 从字⾯意思上看, 本质是个队列, FIFO 先⼊先出&#xff…

Java基础复习

“任何时候我也不会满足&#xff0c;越是多读书&#xff0c;就越是深刻地感到不满足&#xff0c;越感到自己知识贫乏。科学是奥妙无穷的。” ——马克思 目录 一、方法&方法重载 二、运算符 三、数据类型 四、面向对象 1. 面向对象思想 2. 引用传递 3. 访问权限修饰…

高级架构二 Git基础到高级

一 Git仓库的基本概念和流程 什么是版本库&#xff1f;版本库又名仓库&#xff0c;英文名repository,你可以简单的理解一个目录&#xff0c;这个目录里面的所有文件都可以被Git管理起来&#xff0c;每个文件的修改&#xff0c;删除&#xff0c;Git都能跟踪&#xff0c;以便任何…

Docker保存镜像和导入镜像文件(图文详解)

Docker保存镜像和导入镜像文件&#xff08;图文详解&#xff09; Docker 保存和导入镜像文件是 Docker 镜像管理中的两个关键操作&#xff0c;它们在不同的场景下有着各自的意义和用途。以下是对这两个操作的详细说明&#xff1a; 1 基本命令介绍 1.1 Docker 保存镜像&#…

Vue指令(一)--v-html、v-show、v-if、v-else、v-else-if、v-on、v-bind、v-for、v-model

目录 &#xff08;一&#xff09;初识指令和内容渲染指令v-html 1.v-html 案例&#xff1a; 官网的API文档 &#xff08;二&#xff09;条件渲染指令v-show和v-if 1. v-show 2. v-if &#xff08;三&#xff09;条件渲染指令v-else和v-else-if 案例 &#xff08;四…

CV工程师专用键盘开源项目硬件分析

1、前言 作为一个电子发烧友&#xff0c;你是否有遇到过这样的问题呢。当我们去查看函数定义的时候&#xff0c;需要敲击鼠标右键之后选择go to definition。更高级一些&#xff0c;我们使用键盘的快捷键来查看定义&#xff0c;这时候可以想象一下&#xff0c;你左手按下ALT&a…

源码可运行-PHP注册登录源码,PHP实现登陆后才能访问页面

最近有一个项目需要实现会员注册和页面登陆后才能访问&#xff0c;所以简单的HTML是无法实现的&#xff0c;就必须通过PHP、html和Mysql来实现&#xff0c;先给大家看一下登录和注册页的效果图。&#xff08;注册完成后会自动跳转到登录窗口&#xff0c;即使A用户登陆后分享了网…

如何本地存储中的文件路径

文章目录 1. 概念介绍2. 实现方法3. 示例代码我们在上一章回中介绍了"如何实现本地存储"相关的内容,本章回中将介绍如何实现文件存储.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在上一章回中介绍的本地存储只能存储dart语言中基本类型的数值,如果遇到…