LeetCode 热题 100_反转链表(23_206_简单_C++)(单链表_递归)

LeetCode 热题 100_反转链表(23_206)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
        • 思路一(迭代):
        • 思路二(简化方法一(迭代)代码):
        • 思路三(递归):
      • 代码实现
        • 代码实现(思路一(迭代)):
        • 代码实现(思路二(简化方法一(迭代)代码)):
        • 代码实现(思路三(递归)):
          • 思路三递归函数调用的过程:
        • 以思路三为例完成代码调试

题目描述:

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

输入输出样例:

示例 1:
请添加图片描述

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:
请添加图片描述

输入:head = [1,2]
输出:[2,1]

示例 3:
输入:head = []
输出:[]

提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

题解:

解题思路:

思路一(迭代):

1、通过题目分析,实现翻转链表,这里我们可以逐个结点进行翻转。
例: 1->2->3->4->5->null
第一步:listA:1->null, listB:2->3->4->5->null, 拿出1节点,并让其指向空。

第二步:LsitA:2->1->null, listB:3->4->5->null 将2节点插入在1节点之前,注意保存3节点位置信息。

…           总结上两步:需要3个指针分别存储listA的首结点,listB的首节点,和一个需要移动的节点 。

listA:5->4->3->2->1->null

以第一步->第二步为例*pre=1,*temp=2,*r=2
首先r保存后继节点3(r=3),现在temp可以移动改变指向,temp->next=pre,接下来pre=temp,pre移动到头部
此时移动完成,temp=r,准备下一次的移动。此时
pre=2,*temp=3,*r=3。

2、复杂度分析:
① 时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。
② 空间复杂度:O(1)。

思路二(简化方法一(迭代)代码):

1、我们可以把nullptr看作为listA的首节点,这样我们的转换过程就可以看成一个重复的循环。

2、复杂度分析:
① 时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。
② 空间复杂度:O(1)。

思路三(递归):

1、递归代码讲解请看思路三代码实现下方(函数调用的过程)。
2、复杂度分析:
时间复杂度:O(n),其中 n 是链表的长度。需要对链表的每个节点进行反转操作。
空间复杂度:O(n),其中 n 是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 n 层。

代码实现

代码实现(思路一(迭代)):
ListNode* reverseList1(ListNode* head) {//pre是listA首节点,r代表listB的首节点,temp代表移动节点 ListNode *pre=head,*r=nullptr,*temp=nullptr;if(pre!=nullptr){      r=temp=head->next;  	pre->next=nullptr;while(r!=nullptr){r=temp->next; //暂存后继节点 temp->next=pre;  //修改next指向 pre=temp;temp=r;}}return pre;  
}
代码实现(思路二(简化方法一(迭代)代码)):
ListNode* reverseList2(ListNode* head) {//pre是listA首节点,r代表listB的首节点ListNode *pre=nullptr,*r=head; while(r!=nullptr){//temp代表移动节点 ListNode* temp=r;r=temp->next;    temp->next=pre;pre=temp;temp=r;}return pre;
}
代码实现(思路三(递归)):
ListNode* reverseList3(ListNode* head) {//递归出口,head为null或者head->next为null if (!head || !head->next) {  //①return head;          }ListNode* newHead = reverseList3(head->next);head->next->next = head;  //②head->next = nullptr;     //③return newHead;           //④
}
思路三递归函数调用的过程:
//将reverseList3(ListNode* head)函数递归过程做如下简化表示 
r(1){//①r(2){//①r(3){//①r(4){//①r(5){①返回5结点(到了递归出口) }②这里的head就是r(4)中的41->2->3->4<-5 ③将4结点的next指向nullptr ④返回5结点 }②这里的head就是r(3)中的31->2->3<-4<-5③将3结点的next指向nullptr④返回5结点}②这里的head就是r(2)中的21->2<-3<-4<-5③将2结点的next指向nullptr④返回5结点}②这里的head就是r(1)中的11<-2<-3<-4<-5③将1结点的next指向nullptr,null<-1<-2<-3<-4<-5④返回5结点
}
总结:
1、递归出口中 if (!head || !head->next)!head是防止一开始为空,!head->next是找到最后一个结点 
2、②的目的是为了调转指针的方向
3、③的目的就是为了最后给1的next赋nullptr 
4、④的目的仅仅就是为了保存翻转后的首结点 
以思路三为例完成代码调试
#include<iostream>
#include<vector>
using namespace std;struct ListNode{int val;ListNode* next;ListNode(int x):val(x),next(nullptr){};
};//创建单链表(尾插法)
ListNode* createList(vector<int> &arr){ListNode* head=nullptr;ListNode* tail=nullptr;for(const auto &val:arr){ListNode* newNode = new ListNode(val);if(head==nullptr){head=newNode;tail=newNode;}else{tail->next=newNode;tail=newNode;}}return head;
}ListNode* reverseList3(ListNode* head) {//递归出口,head为null或者head->next为null if (!head || !head->next) {  //①return head;          }ListNode* newHead = reverseList(head->next);head->next->next = head;  //②head->next = nullptr;     //③return newHead;           //④
}int main(){vector<int> arr={1,2,3,4,5};ListNode* head=createList(arr);ListNode* ans=reverseList3(head);while(ans!=nullptr){cout<<ans->val<<"->";ans=ans->next;}cout<<"null"; return 0;
}

LeetCode 热题 100_反转链表(23_206)原题链接
大佬画的递归图解链接(感觉不错)
欢迎大家和我沟通交流(✿◠‿◠)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

49 基于单片机的湿度和光照监测

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于AT89C52单片机&#xff0c;采用DHT11温湿度传感器检测土壤湿度&#xff0c;光敏电阻连接ADC0832数模转换器作为光敏传感器&#xff0c;然后通过LCD1602显示湿度和光照值&#xff0c;如果湿度低…

【C语言】程序设计--算法

文章目录 1. 判断两个数的大小并交换2. 计算三角形面积3. 根据x的值计算y4. 字符大小写转换5. 百钱百鸡问题6. 计算公式y的值7. 输出所有的水仙花数8. 计算n的阶乘9. 下三角数据10. 斐波那契数列11. 学生成绩统计12. 数组的平均值1. 判断两个数的大小并交换 介绍: 从键盘输入…

嵌入式Linux,字符串的处理,以及相关函数详解

C 语言库函数中已经给我们提供了丰富的字符串处理相关函数&#xff0c;基本常见的字符串处理需求都可 以直接使用这些库函数来实现。 1. 字符串输入/输出 在程序当中&#xff0c;经常需要在程序运行过程中打印出一些信息&#xff0c;譬如调试信息、报错信息、中间产生的变量的…

400G智算网络助力知名自动驾驶企业算力训练提效

根据Gartner的最新趋势预测&#xff0c;自动驾驶技术正迅速发展&#xff0c;预计在未来几年内将带来显著的商业效益&#xff0c;特别是在决策智能和边缘人工智能领域。目前&#xff0c;一家领军企业正积极拥抱基于大模型的数字化转型之路&#xff0c;作为自动驾驶领域的佼佼者&…

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(三)

目录 ARC规则 概要 所有权修饰符 __strong修饰符 __weak修饰符 __unsafe_unretained修饰符 ___autoreleasing修饰符 ARC规则 概要 “引用计数式内存管理”的本质部分在ARC中并没有改变&#xff0c;ARC只是自动地帮助我们处理“引用计数”的相关部分。 在编译单位上可以…

数学活动是什么过程?

有专家说&#xff1a;数学活动是建构的操作过程&#xff0c;建构的过程必须是探索、发现和创造的过程。 什么是建构&#xff0c;建构就是构建&#xff0c;就是建立。明明有让人一看就明白的词&#xff0c;人非得弄得云遮雾绕。 也难怪&#xff0c;现在什么都流行上云。 上云…

windows11安装Linux子系统配置大数据hadoop

zai 1、安装linux子系统 1、启用适用于 Linux 的 Windows 子系统 搜索框里面输入<开发>即可跳转&#xff0c;打开开发人员模式 命令行里面输入systeminfo确定是否电脑已经支持虚拟化&#xff0c;是则可以继续安装: 2、然后先启用“适用于 Linux 的 Windows 子系统”可选…

RPC设计--从reactor设计 (IOthread)

主从reactor架构 一般的一个网络IO库都是主从reactor模式&#xff0c;即主线程中有一个MainReactor&#xff0c;其负责监听ListenFd&#xff0c;当接受到新的用户连接时&#xff0c;返回的clientfd并不会加入的MainReacotr&#xff0c;而是在子线程&#xff08;这里称为IO线程&…

微信创建小程序码 - 数量不受限制

获取小程序码&#xff1a;小程序码为圆图&#xff0c;且不受数量限制。 目录 文档 接口地址 请求方式 功能描述 注意事项 获取 scene 值 请求参数 返回参数 对接 请求方法 获取小程序码 调用获取小程序码 总结 文档 接口地址 https://api.weixin.qq.com/wxa/get…

【机器学习】基于SVM、逻辑回归和CNN的手写数字识别:性能对比与应用分析

基于SVM、逻辑回归和CNN的手写数字识别&#xff1a;性能对比与应用分析 1 基于SVM对手写数字识别2 基于逻辑回归对手写数字进行识别3 基于CNN对手写数字进行识别总结对比分析 1 基于SVM对手写数字识别 在使用SVM方法对手写数字进行识别的时候&#xff0c;我采用了一对多&#…

群控系统服务端开发模式-应用开发-邮件工厂电信189发送开发

一、电信189邮件工厂开发 1、添加框架对应的SDK composer require phpmailer/phpmailer 2、添加电信189邮件工厂 在根目录下extend文件夹下Mail文件夹下channel文件夹下&#xff0c;创建电信189邮件发送工厂并命名为DianxinMailSender。记住&#xff0c;一定要在电信189邮件发…

部署loki,grafana 以及springcloud用法举例

文章目录 场景docker 部署grafanadocker-compose部署loki维护配置文件 local-config.yaml维护docker-compose.yml配置启动 grafana 添加loki数据源springcloud用法举例查看loki的explore,查看日志 场景 小公司缺少运维岗位&#xff0c;需要研发自己部署日志系统&#xff0c;elk…

非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 4

三十三、出入库管理 Header.vue导一下,RecordController加一个 //将入库数据和原有数据相加吧//新增PostMapping("/save")public Result save(RequestBody Record record) {return recordService.save(record) ? Result.success() : Result.fail();} GoodsManage.v…

Leetcode—1133. 最大唯一数【简单】Plus

2024每日刷题&#xff08;205&#xff09; Leetcode—1133. 最大唯一数 C 实现代码 class Solution { public:int largestUniqueNumber(vector<int>& nums) {constexpr int MAX 1000;vector<int> count(MAX 1, 0);for(int num: nums) {count[num];}for(int…

如何通过自学成长为一名后端开发工程师?

大家好&#xff0c;我是袁庭新。最近&#xff0c;有星友向我提出了一个很好的问题&#xff1a;如何通过自学成为一名后端开发工程师&#xff1f; 为了解答这个疑问&#xff0c;我特意制作了一个视频来详细分享我的看法和建议。 戳链接&#xff1a;如何通过自学成长为一名后端开…

GCC/G++ Centos离线安装

方式一&#xff08;推荐&#xff09; 官方地址&#xff1a;https://gcc.gnu.org/releases.html 镜像站点1&#xff1a;http://mirrors.aliyun.com/centos/7/os/x86_64/Packages/ 镜像站点2&#xff1a;https://vault.centos.org/7.5.1804/os/x86_64/Packages/ gcc &#xff1a…

工业—使用Flink处理Kafka中的数据_ChangeRecord2

使用 Flink 消费 Kafka 中 ChangeRecord 主题的数据,每隔 1 分钟输出最近 3 分钟的预警次数最多的 设备,将结果存入Redis 中, key 值为

【GoLang】文件操作中perm参数的用法

我们在创建文件时&#xff0c; perm 参数主要用于设置新创建文件的权限&#xff0c;有时是0755&#xff0c;有时是0644。那你知道这些数字都代表什么意思吗&#xff1f; 让我们一个个数字拆开了说&#xff0c;现在从左到右给每个数字一个编号 编号1&#xff1a;通常是0&…

【Selenium】基于 WebDriverWait 爬取带有懒加载的静态页面

0x00 前言 朋友做标书&#xff0c;需要用到每日温度&#xff0c;他的老板让在这个网页手动复制做一个长期表出来&#xff1a;http://www.tianqihoubao.com/lishi/nanjing/month/202412.html 想着帮个忙&#xff0c;做个爬虫脚本吧&#xff0c;忽然发现这个页面很有意思&#xf…

fpga vga

因为 如果是减1的话是会少减1的 因为piel_x会延迟 timescale 1ns / 1psmodule vga(//系统侧input wire clk_sys ,input wire rst_n ,input wire clk ,//在顶层例化的pll产生的input wire locked ,/…