《剑指 Offer--LeetCode 学习计划》-- 链表

news2025/2/9 5:11:24

剑指 Offer 06. 从尾到头打印链表(Easy)

题目描述

  • 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
  • 限制:0 <= 链表长度 <= 10000。

举例说明

  • 示例 1:
    • 输入:head = [1,3,2]。
    • 输出:[2,3,1]。

解题思路

  • 利用递归:先走至链表末端,回溯时依次将节点值加入列表,这样就可以实现链表值的倒序输出。
  • 算法流程:
    • 递推阶段:每次传入 head.next,以 head == null(即走过链表尾部节点)为递归终止条件,此时直接返回。
    • 回溯阶段:层层回溯时,将当前节点值加入列表,即 temp.add(head.val)。
    • 最终,将列表 temp 转化为数组 res ,并返回即可。
  • 代码示例:
    class Solution {
        List<Integer> temp = new ArrayList<Integer>();
        public int[] reversePrint(ListNode head) {
            reverse(head);
            int[] res = new int[temp.size()];
            for (int i = 0; i < res.length; i++) {
                res[i] = temp.get(i);
            }
            return res;
        }
    
        private void reverse(ListNode head) {
            if (head == null) {
                return;
            }
            reverse(head.next);
            temp.add(head.val);
        }
    }
    
  • 复杂度分析:
    • 时间复杂度 O(N): 遍历链表,递归 N 次。
    • 空间复杂度 O(N): 系统递归需要使用 O(N) 的栈空间。

剑指 Offer 24. 反转链表(Easy)

题目描述

  • 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
  • 限制:0 <= 节点个数 <= 5000。

举例说明

  • 示例:
    • 输入: 1->2->3->4->5->NULL。
    • 输出: 5->4->3->2->1->NULL。

解题思路

  • 算法流程:
    • 定义两个指针:pre 和 cur。
    • pre 在前 cur 在后。
    • 每次让 pre 的 next 指向 cur,实现一次局部反转。
    • 局部反转完成之后,pre 和 cur 同时往前移动一个位置。
    • 循环上述过程,直至 pre 到达链表尾部。
  • 代码示例:
    class Solution {
        public ListNode reverseList(ListNode head) {
            ListNode pre = null;
            ListNode cur = head;
    
            while (cur != null) {
                ListNode temp = cur.next;
                cur.next = pre;
                pre = cur;
                cur = temp;
            }
    
            return pre;
        }
    }
    
  • 复杂度分析:
    • 时间复杂度 O(N): 遍历链表使用线性大小时间。
    • 空间复杂度 O(1): 变量 pre 和 cur 使用常数大小额外空间。

剑指 Offer 35. 复杂链表的复制(Medium)

题目描述

  • 请实现 copyRandomList 函数,复制一个复杂链表。
  • 在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
  • 限制:
    • -10000 <= Node.val <= 10000。
    • Node.random 为空(null)或指向链表中的节点。
    • 节点数目不超过 1000。

举例说明

  • 示例 1:
    在这里插入图片描述
    • 输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]。
    • 输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]。
  • 示例 2:
    在这里插入图片描述
    • 输入:head = [[1,1],[2,1]]。
    • 输出:[[1,1],[2,1]]。
  • 示例 3:
    在这里插入图片描述
    • 输入:head = [[3,null],[3,0],[3,null]]。
    • 输出:[[3,null],[3,0],[3,null]]。
  • 示例 4:
    • 输入:head = []。
    • 输出:[]。
    • 解释:给定的链表为空(空指针),因此返回 null。

解题思路

  • 利用哈希表的查询特点,考虑构建原链表节点和新链表对应节点的键值对映射关系,再遍历构建新链表各节点的 next 和 random 引用指向即可。
  • 算法流程:
    • 若头节点 head 为空节点,直接返回 null;
    • 初始化:哈希表 map,节点 cur 指向头节点;
    • 复制链表:
      • 建立新节点,并向 map 添加键值对 (原 cur 节点, 新 cur 节点);
      • cur 遍历至原链表下一节点;
    • 构建新链表的引用指向:
      • 构建新节点的 next 和 random 引用指向;
      • cur 遍历至原链表下一节点;
    • 返回值:新链表的头节点 map[head];
  • 代码示例:
    class Solution {
        public Node copyRandomList(Node head) {
            Map<Node, Node> map = new HashMap<>();
            Node cur = head;
    
            while (cur != null) {
                if (!map.containsKey(cur)) {
                    map.put(cur, new Node(cur.val));
                }
                cur = cur.next;
            }
    
            cur = head;
            while (cur != null) {
                if (cur.next != null) {
                    map.get(cur).next = map.get(cur.next);
                }
                if (cur.random != null) {
                    map.get(cur).random = map.get(cur.random);
                }
                cur = cur.next;
            }
    
            return map.get(head); 
        }
    }
    
  • 复杂度分析:
    • 时间复杂度 O(N):两轮遍历链表,使用 O(N) 时间。
    • 空间复杂度 O(N): 哈希表 map 使用线性大小的额外空间。

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

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

相关文章

谈谈几个常见数据结构的原理

数组 数组是最常用的数据结构&#xff0c;创建数组必须要内存中一块 连续 的空间&#xff0c;并且数组中必须存放 相同 的数据类型。比如我们创建一个长度为10&#xff0c;数据类型为整型的数组&#xff0c;在内存中的地址是从1000开始&#xff0c;那么它在内存中的存储格式如…

【送书福利-第十期】清华社 IT BOOK 多得图书活动 ~!

大家好&#xff0c;我是洲洲&#xff0c;欢迎关注&#xff0c;一个爱听周杰伦的程序员。关注公众号【程序员洲洲】即可获得10G学习资料、面试笔记、大厂独家学习体系路线等…还可以加入技术交流群欢迎大家在CSDN后台私信我&#xff01; 本文目录 一、前言二、内容介绍三、抽奖方…

第一章JUC概述

文章目录 什么是JUC为什么学习好多线程很重要硬件来说软件来说存在的问题 Java多线程相关概念一把锁两个并三个程进程和程序的联系线程和进程的联系管程 用户线程和守护线程JAVA线程 什么是JUC 在 Java 5.0 提供了 java.util.concurrent &#xff08; 简称JUC &#xff09; 包…

Spring Cloud Alibaba - Sentinel源码分析

目录 一、Sentinel核心源码分析 1、Sentinel核心概念 1.1、Node之间的关系 2、Sentinel源码入口 2.1、SlotChain解析 2.2、NodeSelectorSlot解析 2.3、ClusterBuilderSlot解析 一、Sentinel核心源码分析 Sentinel是分布式系统的防御系统。以流量为切入点&#xff0c;通过…

001安装Jenkins

安装JenkinsJenkins 是一个开源自动化服务器http://www.jenkins.io/zh/doc/book/installing/#%E7%B3%BB%E7%BB%9F%E8%A6%81%E6%B1%82 docker docker run \-u root \--rm \-d \-p 8080:8080 \-p 50000:50000 \-v jenkins-data:/var/jenkins_home \-v /var/run/docker.sock:/va…

传感器融合概念及对比

1.多传感器融合的定义 传感器数据融合的定义可以概括为把分布在不同位置的多个同类或不同类传感器所提供的局部数据资源加以综合&#xff0c;采用计算机技术对其进行分析&#xff0c;消除多传感器信息之间可能存在的冗余和矛盾&#xff0c;加以互补&#xff0c;降低其不确实性…

记录好项目D2

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是个旅游门户网站 技术栈&#xff1a;JSPjQueryAjaxechartsSpringSpring…

第四章LockSupport与线程中断

文章目录 线程中断机制面试题什么是中断机制?实现三种中断方式通过一个volatile变量实现通过AtomicBoolean&#xff08;原子布尔型&#xff09;通过Thread类自带的中断api方法实现 API源码分析当前线程的中断标识为true&#xff0c;是不是线程就立刻停止&#xff1f;后手案例-…

Vector-常用CAN工具 - Vector Hardware Manager

本文提供了有关 Vector 用于配置 Vector 接口的新工具Vector 硬件管理器(vHardwareManager) 的一些一般信息。 常见问题 1、什么是vHardwareManager&#xff1f; 2、哪些接口支持vHardwareManager&#xff1f; 3、什么时候需要vHardwareManager&#xff1f; 4、哪里可以下…

chatgpt赋能python:Python如何截图运行效果?

Python如何截图运行效果&#xff1f; 如果你是一位有10年python编程经验的工程师&#xff0c;那么你一定知道在编写程序时调试和调整非常重要。为了更好地调试程序&#xff0c;Python提供了许多进行程序运行效果截图的方法。本文将介绍几种常用的Python截图方法以及它们的优缺…

chatgpt赋能python:Python如何截图运行结果

Python如何截图运行结果 介绍 Python是一种高级编程语言&#xff0c;非常流行。它具有许多有用的功能和库&#xff0c;使其成为许多开发人员的首选编程语言之一。但是&#xff0c;当您运行Python程序并需要与他人共享结果时&#xff0c;您可能需要截图运行结果。在本文中&…

编译3D渲染引擎Horde3D

Horde3D是Github上一款开源的轻量级3D渲染引擎&#xff0c;同时它还支持多个平台。今天我们准备在Mac平台上交叉编译至Android平台。如果需要同时能编译Sample&#xff0c;那么还需要SDL2库。默认情况下&#xff0c;编译Horde3D时不强制下载SDL2&#xff0c;你可以选择强制下载…

chatgpt赋能python:Python怎么快速入门?

Python怎么快速入门&#xff1f; Python是一种易学易用的编程语言。它被广泛应用于各种领域&#xff0c;例如数据科学、自动化、Web开发、游戏开发等等。无论你是从事什么领域&#xff0c;在Python的快速入门上花费越少的时间越好。在本文中&#xff0c;我们将介绍Python的基础…

工作二--注意!!!

1、激活单元格&#xff0c;做数据回显 2、单元格退出编辑模式时&#xff0c;让 实时保存 3、获取数据时&#xff0c;用getGIUID 给数据 唯一id&#xff0c;以防数据名重复 数据结构&#xff1a;是结合接口的id 等 和 组件的数据结构 4、父子结构 下拉框中的 :value 把value值 …

网络安全如何6个月成功上岸?

学前感言: 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了. 2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发. 3.有时多 google,baidu,我们往往都遇不到好心的大神,谁会无聊天天给你做解答. 4.遇到实在搞不懂的,可以先放放,以后再来解…

Haproxy搭建Web高可用群集 【Keepalived+HAProxy 高可用 日志定义 内核优化】

Haproxy HAProxy是可提供高可用性、负载均衡以及基于TCP和HTTP应用的代理&#xff0c;是免费、快速并且可靠的一种解决方案。HAProxy非常适用于并发大&#xff08;并发达1w以上&#xff09;web站点&#xff0c;这些站点通常又需要会话保持或七层处理。HAProxy的运行模式使得它可…

Oracle 查询优化改写(第一章)

第一章 单表查询 1.查询空值 2.将空值转换为实际值 不采用nvl&#xff08;&#xff09;函数&#xff0c;而使用COALESCE函数语法为COALESCE(表达式1,表达式2,...,表达式n)&#xff0c;n>2,此表达式的功能为返回第一个不为空的表达式&#xff0c;如果都为空则返回空值。 注…

每日算法总结——回溯算法、 LeetCode 131. 分割回文串

LeetCode 131. 分割回文串 131. 分割回文串 - 力扣&#xff08;LeetCode&#xff09; 什么是回溯算法&#xff1f; 回溯算法真的是解决排列问题的一大利器&#xff0c;其实很多时候自己不经意间就写出了回溯算法&#xff0c;但是一直没有一个系统的认识&#xff0c;今天做一…

B树:数据结构中的平衡之道

目录 引言&#xff1a;一、定义&#xff1a;二、特点&#xff1a;三、应用场景&#xff1a;总结&#xff1a; 引言&#xff1a; 在计算机科学领域中&#xff0c;数据结构是构建和组织数据的重要工具。其中&#xff0c;B树&#xff08;B-tree&#xff09;作为一种自平衡的搜索树…

用RDMA重新思考有状态流处理

摘要 远程直接内存访问 (RDMA) 硬件弥合了网络和主要内存速度之间的差距&#xff0c;从而验证了网络通常是分布式数据处理系统中的瓶颈的常见假设。然而&#xff0c;高速网络并没有提供“即插即用”的性能&#xff08;例如&#xff0c;使用 IP-overInfiniBand&#xff09;&…