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

news2025/2/15 14:54:03

搜索二维矩阵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;
    }
}

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

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

相关文章

【MySQL在Centos 7环境安装】

文章目录 一. 卸载不必要的环境二. 检查系统安装包三. 卸载这些默认安装包四. 获取mysql官⽅yum源五. 安装mysql yum 源&#xff0c;对⽐前后yum源六. 看看能不能正常⼯作七. 安装mysql服务八. .查看配置⽂件和数据存储位置九. 启动服务并查看服务是否存在十. 登陆⽅法十一. 设…

计算机网络-MPLS基础概念

早期传统IP报文依赖路由器查询路由表转发&#xff0c;但由于硬件技术存在限制导致转发性能低&#xff0c;路由器的查表转发成为了网络数据转发的瓶颈。因此旨在提高路由器转发速度的MPLS&#xff08;Multi-Protocol Label Switching&#xff0c;多协议标签交换&#xff09; 被提…

NO.18十六届蓝桥杯备战|循环嵌套|乘法表|斐波那契|质数|水仙花数|(C++)

循环嵌套 循环嵌套的使⽤ while &#xff0c; do while &#xff0c; for &#xff0c;这三种循环往往会嵌套在⼀起才能更好的解决问题&#xff0c;就是我们所说的&#xff1a;循环嵌套。这三种循环都可以任意嵌套使⽤ ⽐如&#xff1a; 写⼀个代码&#xff0c;打印⼀个乘法⼝…

支持向量机原理

支持向量机&#xff08;简称SVM&#xff09;虽然诞生只有短短的二十多年&#xff0c;但是自一诞生便由于它良好的分类性能席卷了机器学习领域。如果不考虑集成学习的算法&#xff0c;不考虑特定的训练数据集&#xff0c;尤其在分类任务中表现突出。在分类算法中的表现SVM说是排…

LLM - 理解 DeepSeek 的 GPRO (分组相对策略优化) 公式与源码 教程(2)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145640762 GPRO&#xff0c;即 Group Relative Policy Optimization&#xff0c;分组相对的策略优化&#xff0c;是 PPO(Proximal Policy Optimiz…

基于springboot 以及vue前后端分离架构的求职招聘系统设计与实现

基于springboot 以及vue前后端分离架构的求职招聘系统设计与实现 随着互联网技术的飞速发展&#xff0c;求职招聘行业也在不断发生变革。传统的求职招聘方式往往存在着信息不对称、效率低下、交易成本高等问题&#xff0c;导致企业的招聘成本增加&#xff0c;求职者的体验下降…

Spring Boot整合协同过滤算法,实现个性化推荐

1. 引言 在这篇文章中&#xff0c;我们将展示如何使用 Spring Boot 框架与 协同过滤算法 相结合来构建一个简单的推荐系统。推荐系统广泛应用于电商、电影推荐、社交平台等领域。协同过滤算法通过分析用户行为&#xff0c;找出相似的用户或者物品&#xff0c;从而实现个性化推荐…

自己部署 DeepSeek 助力 Vue 开发:打造丝滑的时间线(Timeline )

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 自己…

光谱相机在天文学领域的应用

天体成分分析 恒星成分研究&#xff1a;恒星的光谱包含了其大气中各种元素的吸收和发射线特征。通过光谱相机精确测量这些谱线&#xff0c;天文学家能确定恒星大气中氢、氦、碳、氮、氧等元素的含量。如对太阳的光谱分析发现&#xff0c;太阳大气中氢元素占比约 71%&#xff0…

深度卷积神经网络实战海洋动物图像识别

本文采用深度卷积神经网络作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。YOLOv11以其高效的特征提取能力&#xff0c;在多个图像分类任务中展现出卓越性能。本研究针对5种海洋动物数据集进行训练和优化&#xff0c;该数据集包含丰富的海…

MySQL-mysql zip安装包配置教程

网上的教程有很多&#xff0c;基本上大同小异。但是安装软件有时就可能因为一个细节安装失败。我也是综合了很多个教程才安装好的&#xff0c;所以本教程可能也不是普遍适合的。 安装环境&#xff1a;win11 1、下载zip安装包&#xff1a; MySQL8.0 For Windows zip包下载地址…

ECP在Successfactors中paylisp越南语乱码问题

导读 pyalisp:ECP中显示工资单有两种方式&#xff0c;一种是PE51&#xff0c;一种是hrform&#xff0c;PE51就是划线的那种&#xff0c; 海外使用的比较多&#xff0c;国内基本没人使用&#xff0c;hrform就是pdf&#xff0c;可以编辑pdf&#xff0c;这个国内相对使用的人 比…

PDF另存为图片的一个方法

说明 有时需要把PDF的每一页另存为图片。用Devexpress可以很方便的完成这个功能。 窗体上放置一个PdfViewer。 然后循环每一页 for (int i 1; i < pdfViewer1.PageCount; i) 调用 chg_pdf_to_bmp函数获得图片并保存 chg_pdf_to_bmp中调用了PdfViewer的CreateBitmap函数…

本地部署DeepSeek集成VSCode创建自己的AI助手

文章目录 安装Ollama和CodeGPT安装Ollama安装CodeGPT 下载并配置DeepSeek模型下载聊天模型&#xff08;deepseek-r1:1.5b&#xff09;下载自动补全模型&#xff08;deepseek-coder:1.3b&#xff09; 使用DeepSeek进行编程辅助配置CodeGPT使用DeepSeek模型开始使用AI助手 ✍️相…

无人机雨季应急救灾技术详解

无人机在雨季应急救灾中发挥着至关重要的作用&#xff0c;其凭借机动灵活、反应迅速、高效安全等特点&#xff0c;为救灾工作提供了强有力的技术支撑。以下是对无人机雨季应急救灾技术的详细解析&#xff1a; 一、无人机在雨季应急救灾中的应用场景 1. 灾情侦查与监测 无人机…

DeepSeek本地化部署【window下安装】【linux下安装】

一、window 本地安装指导 1.1、下载window安装包 https://ollama.com/download/OllamaSetup.exe 1.2、点击下载好的安装包进行安装 检测安装是否成功&#xff1a; C:\Users\admin>ollama -v ollama version is 0.5.7有上面的输出&#xff0c;则证明已经安装成功。 配置…

Ae:常见的光照控件和材质控件

在 After Effects中&#xff0c;几种模拟效果都有类似的光照控件和材质控件&#xff0c;比如&#xff0c;焦散、卡片动画、碎片等。 光照控件和材质控件允许用户模拟不同光源、阴影和高光效果&#xff0c;控制表面反射特性&#xff0c;从而实现真实的光照和反射模拟。适用于材质…

【鸿蒙开发】第三十章 应用稳定性-检测、分析、优化、运维汇总

目录​​​​​​​ 1 概述 2 使用Asan检测内存错误 2.1 背景 2.2 原理概述 2.3 使用约束 2.4 配置参数 2.4.1 在app.json5中配置环境变量 2.4.2 在Run/Debug Configurations中配置环境变量 2.5 Asan使能 方式一 方式二 运行ASan 2.6 ASan异常检测类型 heap-buf…

Linux软件编程:IO编程

IO&#xff08;linux输入输出&#xff09; 1. IO概念&#xff1a; I&#xff1a;输入 O&#xff1a;输出 Linux 一切皆是文件 屏幕 -> /dev/tty 磁盘 -> /dev/sda 网卡 键盘 -> /dev/event 鼠标-> /dev/mice 都是一个文件 2. IO操作的对象&#xff1a; 文件 3. 文…

javaEE2

maven 搭建 前后端交互 HTML servlet 后台和数据库交互 servlet jdbc 未来 servlet-->springmvc jdbc-->mybatis-->mybatisplus/jpa javaee-->spring-->springboot SERVLET tomcat ~Apache 服务 Apache(音译为阿帕奇)是世界上使用排名第一的Web服务器…