【剑指offer】学习计划day2

news2024/11/27 4:38:04

 

目录

一. 前言 

二. 从尾到头打印链表

        a.题目

         b.题解分析

          c.AC代码

  二. 反转链表

         a.题目

         b.题解分析

        c.AC代码 

三. 复杂链表的复制

         a.题目

         b.题解分析

         c.AC代码 

一. 前言 

 本系列是针对Leetcode中剑指offer学习计划的记录与思路讲解。详情查看以下链接:

剑指offer-学习计划https://leetcode.cn/study-plan/lcof/?progress=x56gvoct

    本期是本系列的day2,今天的主题是----》链表(简单)

    题目编号:JZ06,JZ24,JZ35

二. 从尾到头打印链表

        a.题目

         b.题解分析

       这题的方法有很多。其一:我们可以先遍历一遍链表,将节点的值放到一个数组中,最后将数组逆置即可。其二:我们可以使用一个辅助栈,利用栈后入先出的特性,将链表每个节点的值压入栈中,然后再依次出栈到数组即可。其三:利用递归,先走至链表末端,回溯时依次将节点值放入 数组返回即可。

          c.AC代码

//普通遍历
int* reversePrint(struct ListNode* head, int* returnSize)
{
	int* ret=(int*)malloc(sizeof(int) * 10000);
	int count = 0;
	struct ListNode* cur = head;
    //将每个节点的值放入数组
	while (cur)
	{
		ret[count++] = cur->val;
		cur = cur->next;
	}
	int left = 0;
	int right = count-1;
    //逆置数组
	while (left < right)
	{
		int tmp = ret[left];
		ret[left] = ret[right];
		ret[right] = tmp;
		left++;
		right--;
	}
	*returnSize = count;
	return ret;
}
//递归法

int ret[10000] = { 0 };//全局数组,用于存放逆序的链表
int* reversePrint(struct ListNode* head, int* returnSize)
{
	if (head == NULL)//到链表尾,开始返回
	{
		*returnSize = 0;
		return NULL;
	}
	reversePrint(head->next, returnSize);
	ret[*returnSize] = head->val;
	(*returnSize)++;
	return ret;
}

  二. 反转链表

         a.题目

         b.题解分析

       本题我们在之前的单链表刷题篇有遇到过,当时我们采用了三种方法:三指针法头插法

递归。我们这里便不再细谈,不了解的小伙伴们可以跳转到往期:【刷题篇】链表(上)http://t.csdn.cn/LcalP

        c.AC代码 

//三指针法
struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* n1 = NULL;
    struct ListNode* n2 = head;

    while (n2)
    {
        struct ListNode* n3 = n2->next; //保存下一结点位置
        n2->next = n1;
        n1 = n2;
        n2 = n3;
    }
    //n2为空时,n1即为反转后表头
    return n1;
}
//头插法
struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* newhead = NULL; //新链表
    struct ListNode* first = head;
    while (first)
    {
        struct ListNode* next = first->next; //保存下一结点
        //进行头插
        first->next = newhead;
        newhead = first;
        first = next;
    }
    //全部结点头插完毕
    return newhead;

}
//递归法
struct ListNode* reverseList(struct ListNode* head) 
{
    if (head == NULL || head->next == NULL) //当只有一个结点、没有结点、递归到最后一个结点时返回
        return head;
    struct ListNode* cur = reverseList(head->next); //找到链表尾结点
    head->next->next = head; //让下一结点指向当前结点
    head->next = NULL; //当前结点指向空
    return cur; //返回反转后头结点
}

三. 复杂链表的复制

         a.题目

         b.题解分析

        本题要求我们对一个复杂链表进行一个深拷贝。假如这只是一个普通的单链表,那我们就可以一边遍历链表一边创建结点,当遍历结束时我们的复制也就完成了。但是这个链表除了有next指针指向下一个结点,还存在着一个随机指针random指向随机的结点。这就意味着当我们复制结点时random指向的结点我们可能还没有创建,如下图所示。所以我们需要变换思路。

        法一:原地+结点拆分

        我们先遍历一遍链表,将每个结点进行复制后放入原结点的后面。然后再第二次遍历给复制的结点的random指针赋值,这样可以确保random指向的结点已经存在。最后再将链表中复制的结点进行拆分,形成一个新链表,返回即可。时间复杂度O(N),空间复杂度O(1)

        法二:哈希表

        我们也可以利用哈希表的查询功能来解题。先遍历一遍链表进行拷贝,每次拷贝结点时在哈希表中构建原结点和新结点的映射关系。然后根据原结点和新结点的映射关系再次遍历一遍链表给新结点的next指针和random指针进行赋值即可。时间复杂度O(N),空间复杂度O(N)

 

         c.AC代码 

//法1,原地+结点拆分

class Solution
{
public:
    Node* copyRandomList(Node* head)
    {
        if (head == NULL)
        {
            return NULL;
        }
        //复制结点到当前结点后
        for (Node* cur = head; cur; cur=cur->next->next)
        {
            Node* pnode = new Node(cur->val);
            pnode->next = cur->next;
            cur->next = pnode;
        }
        //对复制的结点的random指针赋值
        for (Node* cur = head; cur; cur=cur->next->next)
        {
            if (cur->random)
            {
                cur->next->random = cur->random->next;
            }
        }

        //每隔一项进行拆分
        Node* retNode = head->next;//指向新链表的头
        for (Node* cur = head; cur; )
        {
            Node* next = cur->next;
            if (next)
            {
                cur->next = next->next;
            }
            cur = next;
        }
        return retNode;

    }
};
//法2,哈希表

class Solution
{
public:
    Node* copyRandomList(Node* head) 
    {
        unordered_map<Node*, Node*> value;//哈希表,建立索引
        value[NULL] = NULL;
        //第一次遍历建立索引映射
        for (Node* cur = head; cur; cur = cur->next)
        {
            value[cur] = new Node(cur->val);
        }
        //第二次遍历对新结点的指针进行赋值链接
        for (Node* cur = head; cur; cur = cur->next)
        {
            value[cur]->next = value[cur->next];
            value[cur]->random= value[cur->random];
        }
        return value[head]; 
    }
};

以上,就是本期的全部内容啦🌸

制作不易,能否点个赞再走呢🙏

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

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

相关文章

KF-GINS开源代码讲解直播课PPT和学习资源

KF-GINS开源代码讲解直播课PPT和学习资源 文章目录 KF-GINS开源代码讲解直播课PPT和学习资源KF-GINS 组合导航算法原理KF-GINS 代码设计KF-GINS 代码实现KF-GINS 常见问题KF-GINS 扩展直播的部分问题 武汉大学i2Nav团队开源的基于卡尔曼滤波的GNSS/INS组合导航系统&#xff08;…

【UmiJS项目】react-monaco-editor代码编辑器的安装与使用

一、git地址 monaco-editorreact-monaco-editor 二、安装 yarn add monaco-editor yarn add react-monaco-editor yarn add monaco-editor-webpack-plugin注意&#xff1a; monaco-editor 和 monaco-editor-webpack-plugin 需要按照以下对应版本来安装 本人使用的版本如下&a…

西门子PLC加减速时间的算法

1、新建工艺对象&#xff0c;在“动态”中可以设置最大转速&#xff08;30.0&#xff09;和启动/停止转速&#xff08;2.0&#xff09;以及加减速时间&#xff08;也可以计算得出&#xff09;。 加速度的计算方法为&#xff1a;&#xff08;最大转速-启动/停止速度&#xff09;…

ChatGPT、Midjourney不香了吗,New Bing 已向全球个人开放

文章目录 1. 前言2. 教程3. 开始 Bing AI 以上图片均由Bing AI生成。&#xff08;后文给出第一幅图的关键字&#xff09; 本文没有任何广告&#xff0c;放心食用&#xff0c;并且手把手教你怎么配置new bing&#xff0c;有需要的耐心看完哦&#xff0c;不懂的可私信我~ 1. 前…

Yarn安装及配置一件启停

Yarn安装及配置一件启停 数据、程序、运算资源&#xff08;内存、CPU)三者组在一起&#xff0c;才能完成数据的计算处理过程。在单机环境下&#xff0c;三者之间协调配合不是太大问题。为了应对海量数据的处理场景&#xff0c;Hadoop软件出现并提供了分布式处理思想。但是在分…

数据结构——双向链表(保姆级教程,包学包会)

1.双向链表的概念 双向链表就是带头双向循环链表 我们在学完单链表之后&#xff0c;就感觉这个非常简单了&#xff0c;他的主要表现就是拥有头节点&#xff0c;链表永不为空&#xff0c;不需要二级指针&#xff1b;可以通过一个节点找到上一个或者下一个节点&#xff1b;头尾…

MySQL基础-事务详解

本文主要介绍MySQL事务 文章目录 前言事务定义事务四大特性&#xff08;ACID&#xff09; 事务操作事务并发问题事务隔离级别 前言 参考链接&#xff1a; 链接1链接2 事务定义 事务是一组操作的集合&#xff0c;他是一个不可分割的工作单位&#xff0c;事务会把所有的操作作…

微服务入门SpringCloud

一、微服务的组成 注册中心&#xff1a;记录每个微服务调用地址、ip 配置中心&#xff1a;管理每个服务的配置 服务网关&#xff1a;身份校验&#xff0c; 分布式缓存&#xff1a;提升访问数据库的速度。 分布式搜索&#xff1a;海量缓存 消息队列&#xff1a;异步消息&#x…

【C++】还new不出对象?看看C++怎么做~(C++内存管理)

&#x1f9d1;‍&#x1f393;个人主页&#xff1a;简 料 &#x1f3c6;所属专栏&#xff1a;C &#x1f3c6;个人社区&#xff1a;越努力越幸运社区 &#x1f3c6;简 介&#xff1a;简料简料&#xff0c;简单有料~在校大学生一枚&#xff0c;专注C/C/GO的干货分…

Redis---订阅和发布

目录 消息系统命令 消息系统 ​ 发布/订阅&#xff0c;即 pub/sub&#xff0c;是一种消息通信模式&#xff1a;发布者也称为消息生产者&#xff0c;生产和发送消息到存储系统&#xff1b;订阅者也称为消息消费者&#xff0c;从存储系统接收和消费消息。这个存储系统可以是文件系…

安全多方计算:安全定义

参考文献&#xff1a;《密码协议》课程 PPT 文章目录 UM & AM安全定义编译器 Semi-honest & Malicious安全定义半诚实模型恶意模型 编译器Input-CommitmentAugmented Coin-TossingAuthenticated Computation编译器框架 UM & AM 安全定义 异步网络下的多方协议&am…

关于 Kafka 分区程序的关键细节

Apache Kafka 是当今事件流的事实标准。Kafka 如此成功的部分原因是它能够处理大量数据&#xff0c;每秒吞吐量达到数百万条记录&#xff0c;这在生产环境中并非闻所未闻。Kafka设计的一部分使这成为可能&#xff0c;那就是分区。 Kafka 使用分区将数据负载分散到集群中的代理…

UFT描述性编程及综合练习

1、录制登录操作改描述性编程。 登录的用户名、密码在global表中给出。有2组&#xff1a;自己的学号/mercury&#xff0c;自己的学号/123456。将登录的本地对象库清空。 要求&#xff1a; 分别采用直接描述性编程和Description描述性编程实现2组数据登录测试&#xff0c;用repo…

pikvm系统主要软件包解析备忘

PI-KVM让普通家用PC也有能够像数据中心机房里面的IP-KVM一样的功能。 详细信息参考官网&#xff1a;PiKVM HandbookOpen and cheap DIY IP-KVM on Raspberry Pihttps://docs.pikvm.org/ nullOpen and inexpensive DIY IP-KVM based on Raspberry Pi - GitHub - pikvm/pikvm: O…

LeetCode - 34 在排序数组中查找元素的第一个和最后一个位置

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在…

【项目笔记】若干基本社团发现算法介绍

两个衡量指标&#xff1a;边介数 & 模块度 边介数计算&#xff1a; 以下用图来自&#xff1a;https://blog.csdn.net/weixin_44704845/article/details/102686597 选择S为源节点对图搜索&#xff0c;画出S到其他节点的最短路径树 2.给边标数字 1&#xff09; 所有邻近叶…

【YOLO系列】--YOLOv4超详细解读/总结(网络结构)

YOLOv4&#xff08;YOLOv4: Optimal Speed and Accuracy of Object Detection&#xff09;&#xff08;原文&#xff0b;解读/总结&#xff0b;翻译&#xff09; 系列文章&#xff1a; YOLOv1论文解读/总结_yolo论文原文_耿鬼喝椰汁的博客-CSDN博客 YOLOv2论文解读/总结_耿鬼…

软件测试面试至今0 offer,问题到底出在哪儿?

转眼已是四月中旬&#xff0c;求职招聘季也快要结束啦&#xff0c;如果没点真技术 真本事&#xff0c;不了解点职场套路&#xff0c;在今年行情下&#xff0c;找工作可是难上加难。 现在点开微博或者脉脉&#xff0c;只要搜索“招聘”&#xff0c;用“惨不忍睹”来形容也不为过…

【数据结构】经典排序

【数据结构】八大排序 1. 排序的概念和运用1.1 概念1.2 运用 2. 常规的排序算法介绍一. 插入排序1.1 直接插入排序1.2 希尔排序 二. 选择排序2.1 选择排序2.2 堆排序 三. 交换排序3.1 冒泡排序3.2 快速排序3.2.1 Hoare法3.2.2 挖坑法3.2.3 前后指针/左右指针法3.2.4 分治法/递归…

windows11 安装 webassembly,遇到的各种错误

1.最开始是尝试在 虚拟机 centos 7 安装的(因为不想安装vs2015) 但是无奈 各种错误.最终无法解决. 2.尝试在windows安装,吐槽一下官方文档 的安装提示是错误的(太老了) 参考以下文章: https://blog.csdn.net/weixin_45482422/article/details/119459918 https://blog.csdn.…