LeetCode Hot 100——链表(四)

Hot100链表题解析与面试实战技巧 链表作为基础数据结构,通过指针操作实现动态内存管理,在算法面试中具有重要地位。其核心原理是通过节点间的引用关系实现高效插入/删除操作,时间复杂度通常为O(1)。从工程实践角度看,链表广泛应用于内存管理、文件系统等场景,而hot100题库中的链表题目更是大厂面试高频考点。掌握反转链表、环形链表检测等经典题型,不仅能提升指针操作能力,还能培养边界条件处理意识。统计显示,合理使用哑节点可使代码通过率提升28%,而迭代解法相比递归更能体现工程思维。这些技巧对准备技术面试的程序员具有重要价值。 阅读详情

2. 两数相加 - 力扣(LeetCode)

I. 两数相加

核心思路:

  • 使用虚拟头节点简化结果链表的创建和边界处理。
  • 用一个进位变量(carry) 记录每一位相加后的进位(初始为 0)。
  • 同时遍历两个链表,每一步计算:当前位和 = 链表1当前值 + 链表2当前值 + 进位。
  • 新节点的值为当前位和 % 10,更新进位为当前位和 / 10。
  • 当其中一个链表遍历完后,继续处理另一个链表的剩余节点和进位。
  • 最后若仍有进位(如 999 + 1 = 1000),需新增一个节点存储进位。

步骤拆解:

    • 创建虚拟头节点dummy和当前指针current(指向结果链表的当前尾部)。
    • 初始化进位carry = 0。
    • 循环遍历两个链表,直到两个链表都遍历完且进位为 0:
      • 取出两个链表当前节点的值(若节点为空则取 0)。
      • 计算总和sum = val1 + val2 + carry。
      • 创建新节点,值为sum % 10,接在current后面。
      • 更新进位carry = sum / 10。
      • 移动两个链表的指针(若不为空)和current指针。
    • 返回dummy.next(结果链表的头节点)。
    • 进位处理:每一位相加后可能产生进位(0 或 1,因为最大情况是 9+9+1=19,进位为 1),进位会参与下一位的计算。循环条件包含carry != 0,确保最后一位的进位被处理(如 999 + 1 的情况)。
    • 链表长度不同的处理:当一个链表遍历完后,通过val1 = (l1 != null) ? l1.val : 0的方式,将空节点视为 0,继续与另一个链表的剩余节点相加。
    /**
     * 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 addTwoNumbers(ListNode l1, ListNode l2) {
            // 创建虚拟头节点,简化结果链表的构建
            ListNode dummy = new ListNode(0);
            ListNode current = dummy; // 当前指针,指向结果链表的尾部
            int carry = 0; // 进位,初始为0
            
            // 遍历两个链表,直到都为空且没有进位
            while (l1 != null || l2 != null || carry != 0) {
                // 取出当前节点的值(为空则取0)
                int val1 = (l1 != null) ? l1.val : 0;
                int val2 = (l2 != null) ? l2.val : 0;
                
                // 计算当前位的总和(包括进位)
                int sum = val1 + val2 + carry;
                // 新节点的值为总和对10取余
                current.next = new ListNode(sum % 10);
                // 更新进位(总和除以10)
                carry = sum / 10;
                
                // 移动指针
                current = current.next;
                if (l1 != null) l1 = l1.next;
                if (l2 != null) l2 = l2.next;
            }
            
            // 返回结果链表的头节点(跳过虚拟头节点)
            return dummy.next;
        }
    }
    

    19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

    II. 删除链表的倒数第N个结点

    核心思路:

    • 使用双指针法(快慢指针):让快指针比慢指针提前移动 N 步,然后两指针同步移动,当快指针到达链表尾部时,慢指针刚好指向倒数第 N 个节点的前驱节点。
    • 引入虚拟头节点:简化删除头节点的边界情况(例如删除链表的第一个节点时,无需特殊处理)。

    步骤拆解:

      • 创建虚拟头节点dummy,其next指向原链表头节点。
      • 初始化快指针fast和慢指针slow,均指向dummy。
      • 快指针先移动 N 步(确保与慢指针拉开 N 个节点的距离)。
      • 快慢指针同步移动,直到快指针的next为null(快指针到达最后一个节点)。
      • 此时慢指针的next即为倒数第 N 个节点,通过slow.next = slow.next.next删除该节点。
      • 返回dummy.next(修改后的链表头节点)。
      • 双指针的作用:快指针提前移动 N 步后,两指针同步移动,当快指针到达尾部时,慢指针恰好停在倒数第 N 个节点的前驱节点,只需一次遍历即可定位目标节点,时间效率更高。
      /**
       * 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) {
              // 创建虚拟头节点,处理删除头节点的边界情况
              ListNode dummy = new ListNode(0);
              dummy.next = head;
              
              // 初始化快慢指针,均指向虚拟头节点
              ListNode fast = dummy;
              ListNode slow = dummy;
              
              // 快指针先移动n步,与慢指针拉开n个节点的距离
              for (int i = 0; i < n; i++) {
                  fast = fast.next;
              }
              
              // 快慢指针同步移动,直到快指针到达最后一个节点
              while (fast.next != null) {
                  fast = fast.next;
                  slow = slow.next;
              }
              
              // 此时slow.next即为倒数第n个节点,删除它
              slow.next = slow.next.next;
              
              // 返回修改后的链表头节点(跳过虚拟头节点)
              return dummy.next;
          }
      }
      

      24. 两两交换链表中的节点 - 力扣(LeetCode)

      III. 两两交换链表中的节点

      核心思路:

      • 使用虚拟头节点(dummy node) 简化头节点交换的边界处理(例如交换前两个节点时,无需单独修改头节点)。
      • 用一个前驱指针(prev) 指向需要交换的两个节点的前一个节点,便于修改指针指向。
      • 每次交换prev后面的两个节点(node1和node2),步骤如下:
      1. prev.next指向node2(让前驱节点连接到第二个节点)。
      2. node1.next指向node2.next(第一个节点连接到第二个节点的下一个节点)。
      3. node2.next指向node1(第二个节点连接到第一个节点)。
      4. 移动prev到node1(作为下一组交换的前驱)。

      步骤拆解:

      • 重复上述过程,直到没有可交换的节点(即prev后面不足两个节点)。
      • 创建虚拟头节点dummy,其next指向原链表头节点,prev初始指向dummy。
      • 循环交换:
        • 定义node1 = prev.next,node2 = node1.next(若node1或node2为null,则退出循环)。
        • 执行交换操作(修改三个指针指向)。
        • 移动prev到node1。
      • 返回dummy.next(交换后的链表头节点)。

      • 边界条件处理:循环条件prev.next != null && prev.next.next != null确保只有当存在两个可交换的节点时才执行交换,处理了链表长度为奇数(最后一个节点不交换)或空链表的情况。
      /**
       * 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) {
              // 创建虚拟头节点,简化头节点交换的处理
              ListNode dummy = new ListNode(0);
              dummy.next = head;
              ListNode prev = dummy; // 前驱指针,初始指向虚拟头节点
              
              // 循环交换,直到没有可交换的节点(prev后不足两个节点)
              while (prev.next != null && prev.next.next != null) {
                  ListNode node1 = prev.next;      // 第一个节点
                  ListNode node2 = prev.next.next; // 第二个节点
                  
                  // 交换节点
                  prev.next = node2;       // 前驱指向第二个节点
                  node1.next = node2.next; // 第一个节点指向第二个节点的下一个
                  node2.next = node1;      // 第二个节点指向第一个节点
                  
                  // 移动前驱指针到下一组的前一个节点(即当前的第一个节点)
                  prev = node1;
              }
              
              // 返回交换后的链表头节点
              return dummy.next;
          }
      }
      
      LeetCode HOT 100 算法精粹:从分类到实战的解题脉络 本文深入解析LeetCode HOT 100算法题库,从分类方法论到实战技巧全面覆盖。通过双指针、动态规划、回溯等核心算法模板的精讲,帮助开发者系统掌握高频面试题型,提升解题效率与编程能力。特别适合准备技术面试的程序员学习参考。 阅读详情

      相关推荐

      力扣hot100二刷——链表

      第二次刷题不在idea写代码,而是直接在leetcode网站上写,“逼”自己掌握常用的函数。

      weixin_49426115的博客 1824

      LeetCode HOT100刷题笔记(四):链表

      ps:笔记和代码按本人理解整理,重思路

      学习记录 1239

      LeetCode Hot100 刷题笔记(3)—— 链表

      一、链表:相交链表,反转链表,回文链表,环形链表,环形链表 II,合并两个有序链表,两数相加,删除链表的倒数第 N 个结点,两两交换链表中的节点,K 个一组翻转链表,随机链表的复制,排序链表,合并 K 个升序链表,LRU 缓存。 *** Trick:本质将链表转为list,再在list上进行操作,最后转回list。

      qq_51175703的博客 1911

      力扣算法 Java 刷题笔记【链表篇】hot100(四)如何判断回文链表(简单) 3

      1. 寻找回文串 2. 判断一个字符串是否为回文串 3. 判断回文单链表(简单) 优化空间复杂度

      心海非海_のBlog 443

      LeetCode-hot100题解—Day3

      LeetCode-hot100题解—Day3

      m0_49074706的博客 1107

      Nvidia Isaac Sim图形界面 入门教程 2024(3)

      在使用Isaac Sim时,最先接触到的应该是它的图形界面,此处将简单介绍图形界面中常用的一些组件:Isaac Sim的界面的常用内容可以分为几个板块。

      m0_56661101的博客 4547

      LeetCode Hot 100 | 链表(中)· 环与合并(C++ 题解)

      题号题目难度核心技巧时间复杂度空间复杂度142环形链表 II🟡 中等Floyd 判环 + 数学推导找入口O(n)O(1)21合并两个有序链表🟢 简单dummy 头节点 + 双指针归并O(m+n)O(1)2两数相加🟡 中等dummy 头节点 + 进位逐位相加19删除倒数第 N 个节点🟡 中等dummy 头节点 + 快慢指针差 n 步O(n)O(1)24两两交换节点🟡 中等dummy 头节点 + 四指针每轮交换一对O(n)O(1)

      jcm0903的博客 455

      从零开始理解异构算力调度:全国一体化算力算网平台实战解析

      本文深入解析了异构算力调度技术在全国一体化算力算网平台中的实战应用。通过资源抽象层设计、动态感知引擎和跨云调度算法,实现AI训练任务的高效资源分配,显著提升计算效率并降低成本。特别针对GPU等异构算力的智能调度方案,为多云协同环境下的AI开发提供实用指南。

      weixin_28730927的博客 334

      Hot 100算法刷题指南:从入门到面试精通

      算法是计算机科学的核心基础,通过合理的数据结构和高效的计算策略解决复杂问题。掌握常见算法如哈希表、动态规划等,能显著提升代码性能和问题解决能力,在技术面试和工程实践中都至关重要。本文以LeetCode Hot 100为蓝本,系统讲解数组操作、链表处理等高频题型,特别针对两数之和、反转链表等经典问题提供Python/Java双语言实现,并分享开发环境配置、错题本管理等实战技巧,帮助开发者建立完整的算法刷题方法论。

      weixin_30730053的博客 315

      MATLAB AppDesigner 中TextArea保留原有信息并换行显示提示信息

      App Designer 中的文本区域TextArea组件,一般可以用来作为matlab app设计中的信息显示。 app.TextArea.Value = 'Hello Matlab'; Value可以是字符向量、字符向量元胞数组、字符串数组或一维分类数组。这样直接给TextArea赋值,每次赋值都会消除先前的信息,然后显示新的信息。如果想要在app实现保留原有信息、多行信息的输出,在MathWorks官方帮助中心给出了一种方法: cellArrayText{1} = sprintf('%s\n

      我是麻瓜喔的博客 1万+

      Matlab_Marr小波尺度变换图

      多尺度的连续小波变换分解后时间尺度图 墨西哥Marr小波函数: %delta 小波变换尺度 %N     小波函数的长度 %s     原始信号 %g     原始信号某个尺度下的小波变化系数 function g=Singularity_Detection(delta,N,s); %保持信号长度 n=length(s); % 构造墨西哥小帽小波函数 for index_x=1

      桔色小西瓜 6601

      LeetCode Hot 100高效刷题与面试突破指南

      算法与数据结构是程序员面试的核心考察点,其中动态规划、二叉树遍历等经典问题频繁出现在大厂技术面试中。理解算法原理和掌握解题模板能显著提升编码面试通过率,例如动态规划的状态定义和转移方程优化可以解决LeetCode中42%的高频考题。通过系统化的错题管理和代码模板训练,开发者可以在LeetCode周赛(如周赛430)等实战场景快速应用双指针、滑动窗口等技巧。本文基于三年大厂面试官经验,详解如何通过17个关键方法构建解题思维体系,帮助候选人避免常见陷阱并高效准备技术面试。

      weixin_30983353的博客 269

      在centos7部署k8s搭建kubernetes集群

      Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。 Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着(比如用户想让apache一直运行,用户不需要关心怎么去做,Kubernetes会自动去监控,然后去重启,新建,总之,让apache一直提供服务),管理员可以加载一个微型服务,让规划器来找

      山东梅长苏 1万+

      LeetCode Hot 100刷题指南与面试实战技巧

      算法面试准备中,掌握核心数据结构与算法原理至关重要。从数组、链表到二叉树和动态规划,这些基础数据结构构成了算法问题的骨架。通过系统化的刷题训练,不仅能提升编码能力,更能培养解决问题的思维模式。LeetCode Hot 100作为高频考题集合,涵盖了面试中最常见的题型分布,如数组操作占35%,动态规划占18%等。本文结合工程实践,详细介绍如何配置高效刷题环境,使用VS Code等工具提升编码效率,并分享滑动窗口、动态规划等经典算法的优化技巧。针对技术面试场景,还提供了白板编码演练和时间管理模板,帮助开发者在面

      weixin_30258901的博客 473

      TwinCAT3入门教程3——PLC程序变量定义和硬件IO关联

      目录 1、IO输入输出变量定义和硬件关联 1.1 IO输入 1.2 IO输出 1.3 PLC变量和IO模块关联 1.4 测试IO输出点 2、伺服变量关联 1、IO输入输出变量定义和硬件关联 1.1 IO输入 添加全局变量IO_Global 变量定义 (*==========================================IO输入===============================================================*)

      panjinliang066333的博客 1万+

      Cadence PCB 仿真宝典【目录】

      欢迎大家来到《Cadence PCB 仿真宝典》该专栏包括【入门篇】【提升篇】【技巧篇】【疑难篇】四个部分,以供大家参考。大家直接点击大纲中的蓝色标题即可轻松传送。

      fydar的博客 3269

      力扣HOT100合集

      对于当前考虑的元素 nums[i],如果 dp[ j - nums[ i ] ] 为 true,说明可以用前面的元素构成和为 j -nums[ i ] 的子集,那么在加上当前元素 nums[ i ] 的情况下,就可以构成和为 j 的子集,因此 dp[ j ] 更新为 true。这样left往回走会导致错误的结果。最终得到的结果为[[1, 2, 3], [2, 1, 3], [3, 1, 2], [1, 3, 2], [2, 3, 1], [3, 2, 1]],即给定数组[1, 2, 3]的全排列结果。

      qq_61504864的博客 5880

      15、 深入理解Akka微服务:创建与管理体育博彩平台

      本博文深入探讨了如何使用Akka微服务架构为体育博彩平台创建投影和管理事件数据,包括市场投影、投注投影以及数据库投影的实现。同时,介绍了通过gRPC提供HTTP端点以供外部系统访问的方法,并详细说明了在本地环境和Kubernetes中运行应用程序的步骤及配置建议。

      weixin_35756624的博客 96

      Leetcode HOT 100 题目总结(已完结)

      文章目录前引题目博客链接Easy No.1 - No.21 前引 这段时间感觉动态规划已经做伤了 就是真的没什么动力再做下去了 后面没做的也都是难的不行的dp题目了 想着还是要做的 这段时间换点口味 把力扣HOT 100题给全做了 写个总结 题目博客链接 Easy No.1 - No.21 461. 汉明距离 617. 合并二叉树 104. 二叉树的最大深度 206. 反转链表 169. 多数元素 21. 合并两个有序链表 ...

      Love 6's Private Blog 1万+

      jre9下载 jdk9

      (Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

      C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

      基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

      最详细,最简单的力扣(leetcode)hot 100 链表(上)讲解

      这篇文章主要是介绍怎么解决hot 100里面关于链表篇章的问题,保证看了都能够学会。

      yyyCode的博客 2925

      IMSL CNL 7.0.0 (x86-64)Crack

      IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

      力扣hot100

      因为 HashSet 使用的是对象的引用进行比较,所以如果两个节点是同一个节点(即内存地址相同),HashSet 会检测到这个重复的引用,从而判断链表中存在环。我的思路是通过排序后的字符串作为哈希表的键,将原字符串作为值添加到相应的键对应的列表中。否则,更新 merged 列表中最后一个区间的结束值。思路是通过遍历两个链表,计算对应节点值与进位的和,处理进位并构建新链表,最后返回不含虚拟头节点的结果链表。评论区看到一个【还有句话:走到尽头见不到你,于是走过你来时的路,等到相遇时才发现,你也走过我来时的路。

      分享技术,分享经验 1967

      efm32 入门.pdf

      本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

      力扣hot100(链表)

      给你两个单链表的头节点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回null。

      weixin_73787068的博客 1096

      leetcode HOT100总结

      本人菜鸡一枚,历时两个月时间把HOT100题做完(Ctrl C-V)了,做完之后还是感觉到很虚,很多中等题还是不会做,于是乎花几天时间把这100题给总结一下。一方面,对自己的知识梳理;另一方面,便于后续回顾。(完成度99,是因为有一道题目收费,没有做!哈哈哈!)以下所有题目都是用Python3实现的。 下面是对这些题目按照算法进行分类整体,主要包括排序、哈希表、递归\回溯、链表、双指针、动态规划、二分查找、贪心、树、深度优先搜索、广度优先搜索等。 在整理之前,先学习一下Python的基本数据类型有哪些,请

      qq_36561737的博客 4747

      力扣hot100分类整理及解题方法

      对应力扣题号

      lmh_qwq的博客 2641

      力扣hot100【链表】

      思路:公式推导(根据链条长度和快的是慢的两倍关系,推导环内长度与环外长度的倍数关系),再找快慢指针先相遇的地方,根据公式长度倍数关系,设置第三个指针,然后第三个指针与慢指针同时遍历,直到相遇的地方就是环的入口。我的思路,双指针,相差N但是卡了bug进行了边界处理,而且多了一个没必要的pre指针,其实不好,不通用,官方的双指针用了虚拟头节点。我的思路:两个链表一长一短,先把长的提前遍历使两个链表的长度相等,然后同时遍历,如果遍历的节点相等时说明相交,否则不相交。官方:没看,三种方法。没思路,直接看的答案。

      qq_41882808的博客 1053
      上一篇: LeetCode Hot 100——链表(三)
      下一篇: 【苍穹外卖笔记】Day01--环境搭建
      junnhwan
      博客等级 码龄2年 56粉丝 26原创
      评论
      成就一亿技术人!
      拼手气红包6.0元
      还能输入1000个字符
       
       条评论被折叠 查看
      添加红包

      请填写红包祝福语或标题

      个

      红包个数最小为10个

      元

      红包金额最低5元

      当前余额3.43元 前往充值 >
      需支付:10.00元
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付元
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值