LC-搜索二维矩阵II、相交链表、反转链表、回文链表、环形链表、环形链表ll

搜索二维矩阵II

方法:从右上角开始搜索

  • 我们可以从矩阵的右上角开始进行搜索。
  • 如果当前元素 matrix[i][j] 等于 target,我们直接返回 true
  • 如果 matrix[i][j] 大于 target,说明 target 只能出现在左边的列,所以我们将列指针向左移动。
  • 如果 matrix[i][j] 小于 target,说明 target 只能出现在下方的行,所以我们将行指针向下移动。
  • 我们重复这个过程,直到找到目标元素或者行列指针越界。
class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return false;
        }

        int m = matrix.length;//行数
        int n = matrix[0].length;//列数
        int row = 0;//从第一行开始
        int col = n-1;//从最后一列开始

        while(row < m && col >= 0){
            if(matrix[row][col] == target){
                return true;
            }else if(matrix[row][col] > target){
                col--;//当前元素大于目标,左移
            }else{
                row++;//当前元素小于目标,下移
            }
        }

        return false;
    }
}

 相交链表

双指针法

  1. 两个指针分别指向两个链表的头节点
    我们设立两个指针 pApB,分别指向链表 A 和链表 B 的头节点。

  2. 同时移动两个指针

    • 每次移动一个指针,如果当前指针指向的节点为空,则将其指向另一个链表的头节点。
    • 这样做的目的是:让两个指针在遍历完自己的链表后,能够到达另一个链表的头节点,最终相遇的地方就是交点。
  3. 相遇
    如果两个指针相遇,则返回相遇的节点;如果两个指针同时指向 null,则说明链表没有交点。

这种方法的核心思想就是“同步走,互相切换”,确保两个指针走过相同的路程,因此可以在 O(m + n) 时间复杂度内解决问题。

设「第一个公共节点」为 node ,「链表 headA」的节点数量为 a ,「链表 headB」的节点数量为 b ,「两链表的公共尾部」的节点数量为 c ,则有:

头节点 headA 到 node 前,共有 a−c 个节点;
头节点 headB 到 node 前,共有 b−c 个节点;

考虑构建两个节点指针 A​ , B 分别指向两链表头节点 headA , headB ,做如下操作:

指针 A 先遍历完链表 headA ,再开始遍历链表 headB ,当走到 node 时,共走步数为:
a+(b−c)
指针 B 先遍历完链表 headB ,再开始遍历链表 headA ,当走到 node 时,共走步数为:
b+(a−c)
如下式所示,此时指针 A , B 重合,并有两种情况:

a+(b−c)=b+(a−c)
若两链表 有 公共尾部 (即 c>0 ) :指针 A , B 同时指向「第一个公共节点」node 。
若两链表 无 公共尾部 (即 c=0 ) :指针 A , B 同时指向 null 。
因此返回 A 即可。

/**
 * 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 pA = headA;
        ListNode pB = headB;

        while(pA != pB){
            pA = (pA == null) ? headB : pA.next;
            pB = (pB == null) ? headA : pB.next;
        }

        return pA;
    }
}

反转链表

双指针: 

/**
 * 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 reverseList(ListNode head) {
        ListNode cur = head,pre = null;

        while(cur != null){
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }

        return pre;
    }
}

 回文链表

思路:

  1. 找到链表的中间节点:使用快慢指针,慢指针每次走一步,快指针每次走两步,最终快指针会指向链表的尾部,慢指针则会指向链表的中间节点。
  2. 反转后半部分链表:将链表的后半部分进行反转,反转后的链表与前半部分进行比较。
  3. 比较前后部分:比较反转后的后半部分与前半部分的节点值,如果相同,则该链表是回文链表。
/**
 * 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 boolean isPalindrome(ListNode head) {
        if(head == null || head.next == null){
            return true;//链表为空或只有一个元素
        }

        ListNode slow = head,fast = head;

        //快指针走两步,慢指针走一步,直到快指针到达末尾
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }

        //反转链表的后半部分
        ListNode secondHalf = reverse(slow);
        ListNode firstHalf = head;

        //比较前后部分的节点值
        while(secondHalf != null){
            if(firstHalf.val != secondHalf.val){
                return false;
            }
            firstHalf = firstHalf.next;
            secondHalf = secondHalf.next;
        }
        return true;
    }

    public ListNode reverse(ListNode head){
        ListNode prev = null,curr = head;
        while(curr != null){
            ListNode temp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = temp;
        }
        return prev;
    }
}

环形链表

  • 初始化指针:使用两个指针,slowfastslow 每次走一步,fast 每次走两步。
  • 判断是否相遇:如果存在环,slowfast 会在环内相遇。如果没有环,fast 会指向 null,即链表的末尾。
  • 结束条件
    • 如果 slowfast 相遇,则说明链表有环,返回 true
    • 如果 fast 到达 null,则说明链表没有环,返回 false
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null){
            return false;
        }

        ListNode slow = head,fast = head;

        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;

            if(slow == fast){
                return true;
            }
        }

        return false;


    }
}

环形链表ll

  • 使用快慢指针检查链表是否有环。
  • 如果有环,重新定位慢指针到头节点,同时让慢指针和快指针都以相同的速度(每次一步)向前走,直到它们相遇。
  • 相遇的节点就是入环的第一个节点。
/**
 * 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) {
        if(head == null || head.next == null){
            return null;
        }

        ListNode slow = head,fast = head;

        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;

            if(slow == fast){
                //找到环的起点
                ListNode pointer = head;
                while(pointer != slow){
                    pointer = pointer.next;//pointer从头节点开始走
                    slow = slow.next;//slow从相遇点开始走
                }
                return pointer;
            }
        }

        return null;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Win11配置wsl、ubuntu、docker

系统要求 安装WSL。 开通虚拟化&#xff1a; 准备工作 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestartdism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestartwsl --set-default-versi…

达梦tpcc压测

造数 在这个日志输出中&#xff0c;主要执行了一系列数据库操作&#xff0c;涵盖了数据库信息检查、表的创建与数据加载、索引的添加、数据验证等步骤。具体分析如下&#xff1a; 数据库信息检查&#xff1a; 查询了数据库的版本、实例名称、日志文件大小、字符集等信息。 删…

MySQL技术公开课:Mysql-Server-8.4.4 Innodb 集群搭建与维护

MySQL技术公开课 - Mysql-Server-8.4.4 Innodb 集群搭建与维护 讲课内容&#xff1a; 1、Innodb集群框架介绍 2、Innodb集群部署(mysql-Server、mysql-shell、mysql-router安装配置) 3、Innodb集群维护(主备切换、启动与关闭、故障排除) Mysql-server商业版目前最新的是8.…

TCP/IP参考模型和网络协议

由于国防部担心他们一些重要的主机、路由器和互联网关可能会突然崩溃&#xff0c;所以网络必须实现的另一目标是网络不受子网硬件损失的影响&#xff0c;已经建立的会话不会被取消&#xff0c;而且整个体系结构必须相当灵活。 TCP/IP是一组用于实现网络互连的通信协议。Interne…

机器学习-02-机器学习算法思想以及在各行各业的应用

总结 本系列是机器学习课程的第02篇&#xff0c;主要介绍机器学习算法思想以及在各行各业的应用 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 定义问题&#xff08;Problem Definition&#xff09; -> 数据收集(Data Collection) -> 数据分割(Data…

无须高配电脑-ChatboxAI 利用SiliconCloud 接入在线deepseek

Deepseek官方api调用 方式收费&#xff0c;官网提供的在线推理又经常出现”服务器繁忙&#xff0c;请稍后再试“的问题。本文借助本地聊会客户端 ChatboxAI&#xff0c; 通过SiliconCloud 平台来接入各种在线大模型&#xff0c;包括Deepseek. ChatboxAI(完全免费) Chatbox AI…

RocketMQ及和Kafka的区别

目录 1 从场景入手2 RocketMQ是什么&#xff1f;3 RocketMQ及和Kafka的区别3.1 在架构上做了减法3.1.1 简化协调节点3.1.2 简化分区3.1.3 底层存储3.1.3.1 Kafka底层存储3.1.3.1 RocketMQ底层存储 3.1.4 简化备份模型3.1.4.1 Kafka备份模型3.1.4.2 RocketMQ备份模型 3.1.5 Rock…

一文深入了解DeepSeek-R1:模型架构

本文深入探讨了 DeepSeek-R1 模型架构。让我们从输入到输出追踪 DeepSeek-R1 模型&#xff0c;以找到架构中的新发展和关键部分。DeepSeek-R1 基于 DeepSeek-V3-Base 模型架构。本文旨在涵盖其设计的所有重要方面。 &#x1f4dd; 1. 输入上下文长度 DeepSeek-R1的输入上下文长…

在 PyCharm 中接入deepseek的API的各种方法

在 PyCharm 中接入 DeepSeek 的 API&#xff0c;通常需要以下步骤&#xff1a; 1. 获取 DeepSeek API 密钥 首先&#xff0c;确保你已经在 DeepSeek 平台上注册并获取了 API 密钥&#xff08;API Key&#xff09;。如果没有&#xff0c;请访问 DeepSeek 的官方网站注册并申请 …

java每日精进 2.13 Ganache(区块链本地私有化部署)

需求&#xff1a;使用区块链实现数据村存储&#xff0c;记录一些不可篡改的交互信息&#xff0c;网络环境为内外网均需要部署&#xff1b; 1.准备工作&#xff08;软件安装&#xff09; 1.1 安装 Node.js 和 npm 1.2 安装 Ganache 地址如下&#xff1a;windows有可视化界面 &a…

【深度学习】多目标融合算法(四):多门混合专家网络MMOE(Multi-gate Mixture-of-Experts)

目录 一、引言 二、MMoE&#xff08;Multi-gate Mixture-of-Experts&#xff0c;多门混合专家网络&#xff09; 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 2.3.1 业务场景与建模 2.3.2 模型代码实现 2.3.3 模型训练与推理测试 2.3.4 打印模型结构 三、总结 一、…

sqli-labs靶场实录(四): Challenges

sqli-labs靶场实录: Challenges Less54确定字段数获取数据库名获取表名获取列名提取密钥值 Less55Less56Less57Less58爆库构造爆表构造爆列构造密钥提取构造 Less59Less60Less61Less62爆库构造 Less63Less64Less65免责声明&#xff1a; Less54 本关开始上难度了 可以看到此关仅…

使用Redis实现分布式锁,基于原本单体系统进行业务改造

一、单体系统下&#xff0c;使用锁机制实现秒杀功能&#xff0c;并限制一人一单功能 1.流程图&#xff1a; 2.代码实现&#xff1a; Service public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderSe…

Python + WhisperX:解锁语音识别的高效新姿势

大家好&#xff0c;我是烤鸭&#xff1a; 最近在尝试做视频的质量分析&#xff0c;打算利用asr针对声音判断是否有人声&#xff0c;以及识别出来的文本进行进一步操作。asr看了几个开源的&#xff0c;最终选择了openai的whisper&#xff0c;后来发现性能不行&#xff0c;又换了…

【Linux】Ubuntu Linux 系统——Node.js 开发环境

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天星期五了&#xff0c;同时也是2025年的情人节&#xff0c;今晚又是一个人的举个爪子&#xff01;&#xff01; &#x1f642; 本文是有关Linux 操作系统中 Node.js 开发环境基础知识&#xff0c;后续我将添加更多相关知识噢&a…

Oracle查看执行计划

方式一&#xff08;查看的真实的使用到的索引&#xff09; 1.执行解释计划 2.查看结果 可以看到使用了RANGE SCAN范围扫描的索引 方式二&#xff08;查看的是预测的可能会用到的索引&#xff09; 1.执行解释计划sql explain plan for select * from COURSE where COURSE_…

百度 AI开源!将在6月30日开源文心大模型4.5系列

【大力财经】直击互联网最前线&#xff1a;百度近期动作频频&#xff0c;先是宣布将在未来数月陆续推出文心大模型4.5系列&#xff0c;并于6月30日正式开源。 据大力财经了解&#xff0c;自DeepSeek开源之风盛行全球后&#xff0c;开源闭源路径的选择就成为AI领域的热门话题&a…

【DDD系列-2】风暴出的领域模型

为什么使用DDD​ 三个问题​ 1.为什么我们的系统越做越多&#xff0c;越来越庞大&#xff0c;还需要不断的重构&#xff1f;​ 2.为什么我们的系统业务越来越复杂&#xff0c;服务层的代码越来越多难以维护&#xff0c;不敢维护&#xff1f;​ 3.为什么一旦业务变化或者数据…

基于YALMIP和cplex工具箱的微电网最优调度算法matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 系统建模 4.2 YALMIP工具箱 4.3 CPLEX工具箱 5.完整工程文件 1.课题概述 基于YALMIP和cplex工具箱的微电网最优调度算法matlab仿真。通过YALMIP和cplex这两个工具箱&#xff0c;完成微电网的最优调…

visual studio导入cmake项目后打开无法删除和回车

通过Cmakelists.txt导入的项目做删除和回车无法响应&#xff0c;需要点击项目&#xff0c;然后选择配置项目就可以了