递归算法练习

 递归算法是所有算法中较难的一种,依靠他代码的简洁和清晰地逻辑很受人们喜欢,但是新手入门递归还是会被他不同寻常的思路吓到,其实面对递归问题我们只需要看清题目,分析出要求,有清晰的解题思路,只要仔细分析,就会很简单的解决问题。
 提到递归,大多数题目就都离不开二叉树,这只不过是其中的一种,我们来做一做其他类型的题目,提高我们分析递归问题的逻辑能力和分析能力,由浅入深,从而掌握递归。
第一题
合并两个有序链表
在这里插入图片描述
这道题我们可以搞一个虚拟节点,很容易就能解决这道问题。
 但是如果我们用递归的方法去解决这道题目,我们需要思考递归的每一步需要做什么,将一个大问题划分为数个小问题来解决。
递归需要我们做什么呢?给定两个链表,将他们合并,然后返回头节点。
在这里插入图片描述
 我们判断两个链表的首元素后,假设是list1val大于list2val,就向后连接list2的节点,此时剩下的工作就是连接list1的节点和list2的剩余节点,就是list1list2剩余节点的合并问题,切记我们呢还需要返回头节点。
在这里插入图片描述
 递归问题还需要判断的就是何时结束,这道题目就是判断一方如果是空节点,就直接将另一方的节点连接起来就好。
在这里插入图片描述
 因为我们返回的是头节点,所以每次只需要将他们连接起来即可。这个操作就是使前边的节点的next等于后续返回的头节点,这样就将两个链表的节点全部连接起来了。
代码如下

class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {if(list1==nullptr)//遇到空节点就返回另一个节点的头指针{return list2;}if(list2==nullptr){return list1;}if(list1->val>list2->val){list2->next=mergeTwoLists(list1,list2->next);//接收返回的节点并链接return list2;}else{list1->next=mergeTwoLists(list1->next,list2);return list1;}}
};

第二题
反转链表
在这里插入图片描述
 这道题如果直接来做的话,使用一个虚拟头节点,然后定义一个节点指针一直头插就可以解决,或者就是设置三个指针变量,从前往后依次改变指针的方向。
头插法

ListNode* reverseList(ListNode* head) {ListNode* newnode=new ListNode;ListNode*cur=nullptr;while(head!=nullptr){newnode->next=head;ListNode* next=head->next;//保留下一个节点,防止下一步操作导致链表断开head->next=cur;cur=head;head=next;}return newnode->next;}

直接改变结点指针的方法

class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* prev = nullptr;ListNode* curr = head;while (curr) {ListNode* next = curr->next;curr->next = prev;prev = curr;curr = next;}return prev;}
};

 如果使用递归的思想来解决这道问题,我们呢还是需要考虑递归的每一步是要做什么。
 我们需要将这个问题拆分为几个小问题来解决,不仅需要改变所有节点的指向,还要将链表的头节点返回回来。
在这里插入图片描述
 拆分成子问题,一直遍历到最后一个节点,将该节点返回,递归过程中不仅要将新的头节点层层返回回去,还要改变指针指向。
在这里插入图片描述
代码如下

ListNode* reverseList(ListNode* head) {if(head==nullptr||head->next==nullptr){return head;}ListNode* newnode=reverseList(head->next);//接收返回值head->next->next=head;//改变指针指向head->next=nullptr;//统一处理return newnode;//层层递归返回新的头节点}

第三题
两两交换链表中的节点

在这里插入图片描述
 这道题要求我们不是修改链表的节点中存放的值,使用递归算法解决,还是要拆分问题。将一个大的问题拆分为小的子问题。
 单看每一步,我们需要做的是将两个节点翻转,返回新的头结点,至于递归结束的条件,很明显,如果只有一个节点或者节点为空就直接返回该节点即可。因为如果是空,就直接链接上了,如果只有一个节点,这个节点的next为空,依然成立。
 现在就是如何翻转两个节点并且返回新节点的问题了。如图
在这里插入图片描述
 接下来就是改变headcurnext的指向,因为我们已经保留k节点的指针了,所以curnext可以放心修改,然后就是接受返回值。
在这里插入图片描述
 在接下来的子问题中,做同样的步骤,翻转3,4节点,返回新的头结点,此时上一次递归的next指针就可以接收这个返回值,将链表连接起来。

代码如下

class Solution {
public:ListNode* swapPairs(ListNode* head) {ListNode* newnode=nullptr;if(!(head&&head->next)){return head;}ListNode*cur=head->next;ListNode*k=cur->next;head->next=swapPairs(k);cur->next=head;return cur;}
};

第四题
在这里插入图片描述
 这道题让我们求xn次幂,题目介绍很简单,这道题我们也可以直接使用库里面的函数直接解决,但是这样就体现不出这道题的意义了,来尝试一下用递归的方法解决这个问题。
首先来说直接算的话为什么不好呢?
 就比如2的8次方,我们再已经知道2的4次方是多少之后,我们可以只使用一次乘法就得出结果,但是如果一步一步算,我们还要再乘4次才能得到相应的结果。
 所以我们在求x的n次方时,可以先求出x的n/2次方,然后让他们想乘就可以了。我们写一个pow函数帮助我们实现这个功能。
此时会出现两个问题
 如果是奇数怎么办?递归出口应该是怎么样的呢?举例来分析一下

  • 29 需要计算的话,因为是奇数,所以再最后返回两个24时,还要再乘以一个2。
  • 求24时,结果是两个2^2相乘。
  • 求22时,此时为两个2相乘。如果递归的过程中,n等于1时,就直接返回x即可。

 还要注意,n有可能是负数,所以如果n为负数,就直接用1除以返回的结果,在传递参数时将n变为-n即可。

 还要注意n为0的情况,我们返回1就可以了。

在这里插入图片描述

 这道题还会出现数据溢出的情况,我们可以将n的类型写为long long就可以解决。
代码如下

double pow(double x, long long n)
{if (n == 1){return x;}double tmp = pow(x, n / 2);return n % 2 == 0 ? tmp * tmp : tmp * tmp * x;
}
double myPow(double x, int n) {if(n==0){return 1.0;}return n < 0 ? 1.0 / pow(x, -(long long)n) : pow(x, n);
}

本文到此结束,有收获还请一键三连支持哦。

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

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

相关文章

软考--软件设计师(软件工程总结2)

目录 1.测试方法 2.软件项目管理 3.软件容错技术 4.软件复杂性度量 5.结构化分析方法&#xff08;一种面向数据流的开发方法&#xff09; 6.数据流图 1.测试方法 软件测试&#xff1a;静态测试&#xff08;被测程序采用人工检测&#xff0c;计算机辅助静态分析的手段&…

虚拟机打不开

问题 另一个程序已锁定文件的一部分&#xff0c;进程无法访问 打不开磁盘“G:\centeros\hadoop104kl\hadoop100-cl2.vmdk”或它所依赖的某个快照磁盘。 模块“Disk”启动失败。 未能启动虚拟机。 原因 前一次非正常关闭虚拟机导致.lck 文件是VMWare软件的一种磁盘锁文件&…

特定领域软件体系结构

1.DSSA的定义 简单地说&#xff0c;DSSA&#xff08;Domain Specific Software Architecture&#xff09;就是在一个特定应用领域中为一组应用提供组织结构参考的标准软件体系结构。 从功能覆盖的范围的角度有两种理解DSSA中领域的含义的方式&#xff1a; &#xff08;1&#x…

极海APM32电机驱动板记录(二)

文章目录 1、解除写保护2、极海驱动板资源概述3、新建工程4、点灯5、嘀嗒定时器6、中断7、串口打印8、adc读取9、i2c尝试10、定时器测试11、电机驱动pwm测试 上一篇文章算是简单了解了一下极海的板子开发环境吧&#xff0c;结果前几天板子来了&#xff0c;然后发现一个大bug&am…

继承 多态 接口 抽象

继承&#xff1a; 继承需要我们学习的点&#xff1a; 什么是继承&#xff0c;继承的好处继承的特点子类到底能继承父类的那些内容&#xff1f;继承中&#xff1a;成员变量的访问特点继承中&#xff1a;成员方法的访问特点继承中&#xff1a;构造方法的特点This,super使用总结…

Docker Desktop 不支持 host 网络模式

先把这个结论的放在前面&#xff0c;直接访问链接就能看到官方文档中已经明确说了不支持。 参考链接&#xff1a;docker desktop for windows 不支持 host 网络模式 以前对于 docker 的网络模式&#xff0c;一直只是了解&#xff0c;没有亲自尝试过。结果今天在尝试 docker 的 …

如何同时安全高效管理多个谷歌账号?

您的业务活动需要多个 Gmail 帐户吗&#xff1f;出海畅游&#xff0c;Gmail账号是少不了的工具之一&#xff0c;可以关联到Twitter、Facebook、Youtube、Chatgpt等等平台&#xff0c;可以说是海外网络的“万能锁”。但是大家都知道&#xff0c;以上这些平台注册多账号如果产生关…

蓝桥集训之垒骰子

蓝桥集训之垒骰子 核心思想&#xff1a;矩阵乘法 f[i]存顶面数值 构造a矩阵 使得*f[i] f[i-1]a 则f[i] f[1] * an 快速幂优化 #include <iostream>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N 6,m…

Oracle APEX 23.2版本 使用应用程序工作副本进行协作开发

现状描述&#xff1a; 当前APEX协作开发都是在同一应用程序下进行的&#xff0c;这样做有可能因同一时间对同一数据进行操作造成锁表或其他问题&#xff0c;Oracle APEX23.2版本迭代后新增了部分功能&#xff0c;可以创建应用程序的工作副本来修复错误、添加功能&#xff0c;然…

C++ setmap

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;C知识分享⏪   &#x1f69a;代码仓库:C高阶&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C知识   &#x1f51d;&#x1f51d; 目录 前言 一.树形结构的关联式容器 &#x…

移动开发技术历史演化简介h5,跨平台,原生的各种技术实现方案的简单介绍

移动端的开发技术是指针对移动设备如智能手机和平板电脑等便携终端进行应用程序和服务创建的过程。本文将主要介绍一下移动端的开发技术的历史进化历程。讲述h5&#xff0c;跨平台&#xff0c;原生的各种技术实现方案和他们各自的优势与不足。 移动开发&#xff0c;不仅是编程技…

在Ubuntu系统下连接远程Ubuntu服务器

本篇文章介绍&#xff0c;如何在Ubuntu系统下连接远程Ubuntu系统并传输文件。 一. 连接远程Ubuntu服务器。 1. 打开命令行&#xff0c;输入 : sudo apt-get update &#xff0c; 对系统进行更新。 2. 安装 OpenSSH Server&#xff0c;输入 &#xff1a; sudo apt-get insta…

聊一聊电子邮件?

电子邮件是什么&#xff1f; 电子邮件是一种基于客户/服务器架构的应用。功能是实现人与人之间的交流。直到现在&#xff0c;电子邮件依然是当前因特网 注意&#xff1a;基于客户/服务器方式和基于B/S架构不一样&#xff01;客户/服务器表示的范围更广&#xff0c;当基于客户…

Python 网络请求:深入理解Requests库

目录 引言 一、Requests库简介 二、安装与基本使用 三、requests库的特性与优势 四、requests库在实际应用中的案例 1.get请求 2.post请求 3.超时重试 4.headers设置 5.session会话 6.携带cookie​​​​​​​ 7.携带代理​​​​​​​ 8.携带身份认证​​​​​…

爬虫 新闻网站 并存储到CSV文件 以红网为例 V1.0

爬虫&#xff1a;红网网站&#xff0c; 获取当月指定关键词新闻&#xff0c;并存储到CSV文件 V1.0 目标网站&#xff1a;红网 爬取目的&#xff1a;为了获取某一地区更全面的在红网已发布的宣传新闻稿&#xff0c;同时也让自己的工作更便捷 环境&#xff1a;Pycharm2021&#…

【CSS】浮动笔记及案例

CSS浮动 1. 认识浮动 float属性可以指定一个元素沿着左侧或者是右侧放置&#xff0c;允许文本和内联元素环绕它 float属性最初只使用文字环绕图片但却是早起CSS最好用的左右布局方案 绝对定位、浮动都会让元素脱标&#xff0c;以达到灵活布局的目的可以通过float属性让元素脱…

UE4_材质节点

UE4_材质节点 2017-12-07 13:56 跑九宫格 跑UV 评论(0)

arm裸机-1、定时器pwm

时钟配置 我们使用s3c2440&#xff0c;主频12M&#xff0c;查看用户手册 通过锁相环抬升到400MHZ&#xff0c;分成三条通路&#xff0c;通过HHDIVN和PDIVN配置频率比&#xff0c;这个频率比配置手册已经给出。 配置MPLL主频400Mhz&#xff0c; 通过这个公式算出MPLL s、p、m都…

hive 慢sql 查询

hive 慢sql 查询 查找 hive 执行日志存储路径&#xff08;一般是 hive-audit.log &#xff09; 比如&#xff1a;/var/log/Bigdata/audit/hive/hiveserver/hive-audit.log 解析日志 获取 执行时间 执行 OperationId 执行人 UserNameroot 执行sql 数据分隔符为 \001 并写入 hiv…

C语言——调试技巧

1.Debug和Release的介绍 Debug 通常称为调试版本&#xff0c;它包含调试信息&#xff0c;并且不作任何优化&#xff0c;便于程序员调试程序。Release 称为发布版本&#xff0c;它往往是进行了各种优化&#xff0c;使得程序在代码大小和运行速度上都是最优 的&#xff0c;以便用…