体系班第十七节(经典递归)

1汉诺塔 

从左移到最右,圆盘必须满足小压大原则

写一个大方法,大方法包括两步:第一步将最后一个圆盘上面的所有的放到第二个塔上面,然后将最后一个圆盘放到最后塔上面,再把第二个塔上面圆盘全放在第三个塔上面

#include <iostream>using namespace std;// 将 1~N 层圆盘从左 -> 右
void leftToRight(int n);// 将 1~N 层圆盘从左 -> 中
void leftToMid(int n);// 将 1~N 层圆盘从右 -> 中
void rightToMid(int n);// 将 1~N 层圆盘从中 -> 右
void midToRight(int n);// 将 1~N 层圆盘从中 -> 左
void midToLeft(int n);// 将 1~N 层圆盘从右 -> 左
void rightToLeft(int n);// 汉诺塔问题
void hanoi1(int n) {leftToRight(n);
}void leftToRight(int n) {if (n == 1) { // 基本情况cout << "Move 1 from left to right" << endl;return;}leftToMid(n - 1);cout << "Move " << n << " from left to right" << endl;midToRight(n - 1);
}void leftToMid(int n) {if (n == 1) {cout << "Move 1 from left to mid" << endl;return;}leftToRight(n - 1);cout << "Move " << n << " from left to mid" << endl;rightToMid(n - 1);
}void rightToMid(int n) {if (n == 1) {cout << "Move 1 from right to mid" << endl;return;}rightToLeft(n - 1);cout << "Move " << n << " from right to mid" << endl;leftToMid(n - 1);
}void midToRight(int n) {if (n == 1) {cout << "Move 1 from mid to right" << endl;return;}midToLeft(n - 1);cout << "Move " << n << " from mid to right" << endl;leftToRight(n - 1);
}void midToLeft(int n) {if (n == 1) {cout << "Move 1 from mid to left" << endl;return;}midToRight(n - 1);cout << "Move " << n << " from mid to left" << endl;rightToLeft(n - 1);
}void rightToLeft(int n) {if (n == 1) {cout << "Move 1 from right to left" << endl;return;}rightToMid(n - 1);cout << "Move " << n << " from right to left" << endl;midToLeft(n - 1);
}int main() {// 测试int n = 3; // 圆盘的层数hanoi1(n);return 0;
}

 

递归2:把三个塔分为from other to 

#include <iostream>using namespace std;// 汉诺塔问题
void hanoi2(int n) {if (n > 0) {func(n, "left", "right", "mid");}
}// 递归函数
void func(int N, string from, string to, string other) {if (N == 1) { // 基本情况cout << "Move 1 from " << from << " to " << to << endl;} else {func(N - 1, from, other, to);cout << "Move " << N << " from " << from << " to " << to << endl;func(N - 1, other, to, from);}
}int main() {// 测试int n = 3; // 圆盘的层数hanoi2(n);return 0;
}

2打印一个字符串的全部子序列
递归思路:第一个参数是原字符串,第二个index是当前来到的字符,path是之前已经选好的部分串,第三个参数是所有结果的保存

#include <vector>
#include <string>using namespace std;class Solution {
public:vector<string> subs(string s) {vector<char> str(s.begin(), s.end());string path = "";vector<string> ans;process1(str, 0, ans, path);return ans;}private:void process1(vector<char>& str, int index, vector<string>& ans, string path) {if (index == str.size()) {ans.push_back(path);return;}// 不要索引位置的字符process1(str, index + 1, ans, path);// 要索引位置的字符process1(str, index + 1, ans, path + str[index]);}
};

 3题 求所有不同的子序列,只要改成set结构收集答案即可

4 打印一个字符串的全部排列

去除该字符后需要回溯去恢复现场

#include <vector>
#include <string>using namespace std;class Solution {
public:vector<string> permutation1(string s) {vector<string> ans;if (s.empty()) {return ans;}string path = "";vector<char> rest(s.begin(), s.end());f(rest, path, ans);return ans;}private:void f(vector<char>& rest, string path, vector<string>& ans) {if (rest.empty()) {ans.push_back(path);} else {int N = rest.size();for (int i = 0; i < N; i++) {char cur = rest[i];rest.erase(rest.begin() + i);f(rest, path + cur, ans);rest.insert(rest.begin() + i, cur);}}}
};

 递归2:

不停地做字符串前一位和后一位交换,而且是在原字符串上面交换

#include <vector>
#include <string>using namespace std;class Solution {
public:vector<string> permutation2(string s) {vector<string> ans;if (s.empty()) {return ans;}char* str = &s[0];g1(str, 0, ans);return ans;}private:void g1(char* str, int index, vector<string>& ans) {if (str[index] == '\0') {ans.push_back(string(str));} else {for (int i = index; str[i] != '\0'; i++) {swap(str[index], str[i]);g1(str, index + 1, ans);swap(str[index], str[i]);}}}void swap(char& a, char& b) {char temp = a;a = b;b = temp;}
};

5去重过后的排列

在上一题代码做改动,如果某个字符已经试过了,那就在后面在遇到时就不尝试了

 

#include <vector>
#include <string>using namespace std;class Solution {
public:vector<string> permutation3(string s) {vector<string> ans;if (s.empty()) {return ans;}char* str = &s[0];g2(str, 0, ans);return ans;}private:void g2(char* str, int index, vector<string>& ans) {if (str[index] == '\0') {ans.push_back(string(str));} else {bool visited[256] = { false }; // 记录字符是否已被访问for (int i = index; str[i] != '\0'; i++) {if (!visited[str[i]]) { // 如果字符尚未访问过visited[str[i]] = true; // 标记字符已被访问swap(str[index], str[i]);g2(str, index + 1, ans);swap(str[index], str[i]);}}}}void swap(char& a, char& b) {char temp = a;a = b;b = temp;}
};

 6 递归逆序栈

#include<stack>
using namespace std;
//该函数的功能是返回栈底的元素
int f(stack<int>& s)
{int result = s.top();s.pop();if (s.empty()){return result;}else {int last = f(s);s.push(result);return last;}
}
void reverse(stack<int>& s)
{if (s.empty())return;int i = f(s);reverse(s);s.push(i);
}

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

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

相关文章

C语言的位操作与位字段

C语言中的位操作允许程序员直接在整型变量的单个位或位组上进行操作。这种操作在许多低级编程任务中非常有用&#xff0c;尤其是在嵌入式系统编程中&#xff0c;如硬件操作、设备驱动及性能优化等场景。位操作主要使用以下几种位操作符&#xff1a; & &#xff08;按位与&a…

深入理解TCP:序列号、确认号和自动ACK的艺术

深入理解TCP&#xff1a;序列号、确认号和自动ACK的艺术 在计算机网络的世界里&#xff0c;TCP&#xff08;传输控制协议&#xff09;扮演着至关重要的角色。它确保了数据在不可靠的网络环境中可靠地、按顺序地传输。TCP的设计充满智慧&#xff0c;其中序列号&#xff08;Seq&a…

JavaSE-----认识异常【详解】

目录 一.异常的概念与体系结构&#xff1a; 1.1异常的概念&#xff1a; 1.2一些常见的异常&#xff1a; 1.3异常的体系结构&#xff1a; 1.4异常的分类&#xff1a; 二.异常的处理机制&#xff1a; 2.1 抛出异常&#xff1a; 2.2异常的捕获&#xff1a; 2.3try-catch-&…

某赛通电子文档安全管理系统 DecryptApplication 任意文件读取漏洞复现

0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…

从零开始学习编程:迈出你的编程之路

标题 《从零开始学习编程&#xff1a;迈出你的编程之路》摘要引言如何开始学习编程&#xff1f;1. **明确学习目标**2. **选择编程语言**3. **学习资源**4. **练习编程**5. **参与社区**6. **持之以恒**7. **探索更多** 总结参考资料 博主 默语带您 Go to New World. ✍ 个人主…

阅读 - 二维码扫码登录原理

在日常生活中&#xff0c;二维码出现在很多场景&#xff0c;比如超市支付、系统登录、应用下载等等。了解二维码的原理&#xff0c;可以为技术人员在技术选型时提供新的思路。对于非技术人员呢&#xff0c;除了解惑&#xff0c;还可以引导他更好地辨别生活中遇到的各种二维码&a…

Ubuntu 14.04:PaddleOCR基于PaddleHub Serving的服务部署(失败)

目录 一、为什么使用一键服务部署 二、安装 paddlehub 1.8 2.1 安装前的环境准备 2.2 安装paddlehub 1.8 2.2.1 安装paddlehub 2.2.2 检测安装是否成功 2.2.3 检查本地与远端PaddleHub-Server的连接状态 2.2.4 测试使用 2.3 其他 2.3.1 如何卸载、pip常用命令、常见…

如何保存缓存和MySQL的双写一致呢?

如何保存缓存和MySQL的双写一致呢&#xff1f; 所谓的双写一致指的是&#xff0c;在同时使用缓存(如Redis)和数据库(如MySQL)的场景下,确保数据在缓存和数据库中的更新操作保持一致。当对数据进行修改的时候&#xff0c;无论是先修改缓存还是先修改数据库&#xff0c;最终都要保…

C语言内存函数详解

文章目录 前言一、memcpy函数&#xff08;内存拷贝函数&#xff09;二、memmove重叠拷贝函数三.memset内存设置函数四.memcmp内存比较函数总结 前言 我们之前按学习了C语言标准库中提供了一系列的字符和字符串库函数&#xff0c;接下来我们就学习一下关于内存相关的一些函数。…

Linux环境下Minio的安装部署与启动教程(完整版)

1、概述 MinIO是一个开源、分布式的对象存储系统&#xff0c;专为云原生环境设计。它提供了一个基于标准的Amazon S3兼容接口&#xff0c;使得开发者可以使用熟悉的API在私有云或边缘环境中部署和管理大规模非结构化数据&#xff0c;如图片、视频、日志文件等。 MinIO的核心特…

ChatGLM:基于ChatGLM-6B使用ptuning进行微调,实现类instruction的效果

由于业务需要&#xff0c;调研下怎么训练一个虚拟角色出来&#xff0c;所以找了一些文档参考&#xff0c;其中有一个基于ChatGLM-6B使用ptuning进行微调&#xff0c;实现类instruction的效果的现成的项目&#xff0c;给大家分享下。 一、介绍 由于ChatGLM-6B 不支持instructio…

Linux内核--基本概念/基本结构和组件

提示&#xff1a;本系列文章重点学习Linux内核 Linux内核--基本概念/基本结构和组件 简介一、基础概念1.六项工作内容2.根文件系统&#xff08;Root File System&#xff09;&#xff1a;3.交叉编译&#xff08;Cross-Compilation&#xff09;&#xff1a;4.设备树&#xff08;…

【矩阵】240. 搜索二维矩阵 II【中等】

搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a;每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22…

居民健康监测小程序|基于微信小程序的居民健康监测小程序设计与实现(源码+数据库+文档)

居民健康监测小程序目录 目录 基于微信小程序的居民健康监测小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 1、用户信息管理 2、健康科普管理 5.3公告类型管理 3、论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推…

超越 GPT4,科大讯飞,再出王炸!

哈喽&#xff0c;大家好&#xff01; 去年&#xff0c;科大讯飞星火大模型上线&#xff0c;给大家推荐了一波&#xff0c;演示了其强大的功能&#xff0c;不少小伙伴都立马申请体验了一把&#xff0c;也有私信说非常强大&#xff0c;工作效率提高不少&#xff0c;支持国产大模…

c语言:操作符详解(上)

目录 一、操作符的分类二、二进制和进制转换1.2进制转10进制2.10进制转2进制3.2进制转8进制4.2进制转16进制 三、原码、反码、补码四、算术操作符、-、*、/、%1.**和-**2.*3./4.% 五、移位操作符1.左移操作符2.右移操作符 六、位操作符&#xff1a;&、|、^、~七、赋值操作符…

27.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-数据推测功能的实现

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a; 易道云信息技术研究院VIP课 上一个内容&#xff1a;26.实现生成日志…

Java手写简易数据库--持续更新中

MYDB 0. 项目结构0.1 引用计数缓存框架为什么不使用LRU引用计数缓存缓存框架实现 0.2 共享内存数组 1. 事务管理器--TM1.1 XID 文件XID 规则XID 文件结构读取方式事务状态 1.2 代码实现 2. 数据管理器--DM2.1 页面缓存页面结构页面缓存数据页管理第一页普通页 2.2 日志文件 3. …

MQ 延迟队列

MQ 延迟队列 1. 前言 延迟队列是我们日常开发过程中&#xff0c;经常接触并需要使用到的一种技术方案。前些时间在开发业务需求时&#xff0c;我也遇到了一个需要使用到延迟消息队列的需求场景&#xff0c;因此我也在网上调研了一系列不同的延迟队列的实现方案&#xff0c;在…

【Linux】信号量和线程池

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【Linux】进程通信——共享内存消息队列信号量 目录 &#x1f449;&#x1f3fb;信号量&#x1f449;&#x1f…