【递归、搜索与回溯算法必刷42题:专题一】从汉诺塔问题到快速幂

【递归、搜索与回溯算法必刷42题:专题一】从汉诺塔问题到快速幂

在这里插入图片描述


🎬 个人主页艾莉丝努力练剑
专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:

在这里插入图片描述

🎬艾莉丝的算法专栏简介:

在这里插入图片描述

文章目录


在这里插入图片描述

本文设计专题一算法题链接

面试题 08.06. 汉诺塔问题

21. 合并两个有序链表

206. 反转链表

24. 两两交换链表中的节点

50. Pow(x, n)


1 汉诺塔问题

题目描述

在这里插入图片描述

接下来,我们就来介绍一下这道题的算法原理。

汉诺塔问题(递归解法)

1. 问题描述

汉诺塔问题是一个经典的递归问题,规则如下:

  • 有三根柱子,记为 A(起始柱)B(辅助柱)C(目标柱)
  • A 柱上有 n 个盘子,从小到大叠放(从上到下编号为 1 到 n)。
  • 目标是将所有盘子从 A 移到 C,每次只能移动一个盘子,并且大盘子不能放在小盘子上面
在这里插入图片描述

2. 递归思想

基本情况(递归终止条件)
  • n = 1 时,直接将 A 最上面的盘子移到 C。
递归分解(n ≥ 2)

若要将 A 上的 n 个盘子移到 C,可以分解为三个步骤:

  1. 将 A 上除了最底下的盘子(即上面 n-1 个盘子)移到 B(借助 C 作为辅助柱)。
  2. 将 A 最底下的最大盘子移到 C
  3. 将 B 上的 n-1 个盘子移到 C(借助 A 作为辅助柱)。

这样,规模为 n 的问题被拆分为两个规模为 n-1 的子问题

3. 递归算法流程(函数设计)

函数头
voidhanoi(vector<int>& A, vector<int>& B, vector<int>& C,int n);
  • 1、返回值:无;
  • 2、参数:三个柱子上的盘子,当前需要处理的盘子个数(当前问题规模)。
  • 3、函数作用:将A中的上面n个盘子挪到C中。

递归函数流程:

  • 1、当前问题规模为n=1时,直接将A中的最上面盘子挪到C中并返回;
  • 2、递归将A中最上面的n-1个盘子挪到B中;
  • 3、将A中最上面的一个盘子挪到C中;
  • 4、将B中上面n-1个盘子挪到C中。

解题过程

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

算法实现(C++)

classSolution{public:voidhanota(vector<int>& a, vector<int>& b, vector<int>& c){dfs(a,b,c,a.size());}voiddfs(vector<int>& a, vector<int>& b, vector<int>& c,int n){if(n ==1){ c.push_back(a.back()); a.pop_back();return;}dfs(a,c,b,n -1); c.push_back(a.back()); a.pop_back();dfs(b,a,c,n -1);}// void dfs(x,y,z,int n)// void dfs(x,y,z,n - 1)// z = x.back();// dfs(y,x,z,n - 1);};

上面是面试题的处理,如果是笔试题,就可以不讲武德了——

classSolution{public:voidhanota(vector<int>& a, vector<int>& b, vector<int>& c){ c = a;}};

2 合并两个有序链表

题目描述

在这里插入图片描述

接下来,我们就来介绍一下这道题的算法原理。

解题过程

在这里插入图片描述


在这里插入图片描述

算法实现(C++)

classSolution{public: ListNode*mergeTwoLists(ListNode* l1, ListNode* l2){// 递归出口if(l1 ==nullptr)return l2;if(l2 ==nullptr)return l1;// 比大小if(l1->val <= l2->val){ l1->next =mergeTwoLists(l1->next,l2);return l1;}else{ l2->next =mergeTwoLists(l1,l2->next);return l2;}}};

3 反转链表

题目描述

在这里插入图片描述

接下来,我们就来介绍一下这道题的算法原理。

解题过程

在这里插入图片描述

算法实现(C++)

// 将链表看成一棵树/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */classSolution{public: ListNode*reverseList(ListNode* head){// 细节问题:找出口if(head ==nullptr|| head->next ==nullptr)return head;// 主逻辑 ListNode* newhead =reverseList(head->next); head->next->next = head; head->next =nullptr;// 最终返回结果return newhead;}};

4 两两交换链表中的节点

题目描述

在这里插入图片描述

接下来,我们就来介绍一下这道题的算法原理。

解题过程

在这里插入图片描述

算法实现(C++)

/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */classSolution{public: ListNode*swapPairs(ListNode* head){// 出口if(head ==nullptr|| head->next ==nullptr)return head;// 节点为空或者是个尾节点,就不能交换// 宏观角度看待auto tmp =swapPairs(head->next->next);auto ret = head->next; head->next->next = head; head->next = tmp;// 返回最终结果return ret;}};

5 Pow(x, n)

题目描述

在这里插入图片描述

接下来,我们就来介绍一下这道题的算法原理。

解题过程

在这里插入图片描述


在这里插入图片描述

算法实现(C++)

classSolution{public:doublemyPow(double x,int n)// 主函数{// 细节问题:n可能是负数return n <0?1.0/Pow(x,-(longlong)n):Pow(x,n);}doublePow(double x,longlong n)// 快速幂{// 递归出口if(n ==0)return1.0;// x ^ 0 = 1// 递归double tmp =Pow(x,n /2);return n %2==0? tmp * tmp : tmp * tmp * x;}};

结尾

uu们,本文的内容到这里就全部结束了,艾莉丝再次感谢您的阅读!

结语:希望对学习递归、搜索与回溯算法相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡૮₍ ˶ ˊ ᴥ ˋ˶₎ა

Read more

Python中一切皆对象:深入理解Python的对象模型

Python中一切皆对象:深入理解Python的对象模型

Python中一切皆对象:深入理解Python的对象模型 * 什么是"一切皆对象"? * Python对象的类型层次 * 1. 内置类型对象 * 2. 函数对象 * 3. 类对象和实例对象 * 4. 模块对象 * 对象行为的统一性 * 特殊方法:对象行为的背后 * 对象模型的实际应用 * 性能考虑 * 总结 Python以其"一切皆对象"的设计哲学而闻名,这种设计为语言带来了极大的灵活性和一致性。本文将深入探讨Python的对象模型,解释为什么说"Python中一切皆对象",并通过实例展示这一特性如何影响我们的编程方式。 什么是"一切皆对象"? 在Python中,从简单的数字、字符串到复杂的函数、类甚至模块,所有这些都是对象。这意味着它们都有: 1. 身份(identity):对象在内存中的唯一地址,可通过id()函数获取 2.

By Ne0inhk
Python中的“==“与“is“:深入解析与Vibe Coding时代的优化实践

Python中的“==“与“is“:深入解析与Vibe Coding时代的优化实践

🌟 Python中的"=="与"is":深入解析与Vibe Coding时代的优化实践 * 1. 🧐 `==`与`is`的本质区别 * 2. 🕵️‍♂️ `is`判断对象身份 - 数组与常量池案例 * 案例1:列表对象的身份 * 案例2:小整数常量池 * 案例3:字符串驻留 * 3. 🔍 `==`与`__eq__`魔法函数 * 4. 🔎 类型判断的正确姿势:使用`is` * 5. 🚀 Vibe Coding时代的提示词优化 * 场景1:解释概念 * 场景2:代码生成 * 场景3:调试帮助 * 📊 对比总结表 * 💡 实际应用建议 * 🌈 结语 在Python的奇妙世界中,==和is这两个看似简单的操作符常常让初学者感到困惑。它们如同双胞胎,外表相似却性格迥异。本文将带你深入探索它们的区别,并通过生动的案例和图表展示它们的应用场景,

By Ne0inhk

C++中lower_bound 与 upper_bound 函数详解

目录 一.核心定义与核心区别 lower_bound(下界函数) upper_bound(上界函数) 二.使用前提与参数说明 1. 必须满足的前提 2. 函数参数 3.返回值  三.用法 (1)判断目标值是否存在 (2)计算目标值的出现次数(统计重复元素) (3)在有序容器中插入元素(保持有序) (4)自定义比较函数(降序) lower_bound 和 upper_bound 是 C++ 标准库 <algorithm> 头文件中的二分查找算法,专门用于在有序区间中高效定位元素 一.核心定义与核心区别 函数的头文件: #include <algorithm>

By Ne0inhk
华为OD机试双机位C卷-面试叫号系统 (Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷-面试叫号系统 (Py/Java/C/C++/Js/Go)

面试叫号系统 华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型 华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解 题目描述 某公司举行招聘会,面试官通过叫号系统,按照应聘者的预约先后次序依次呼叫应聘者面试。如果被叫到的应聘者没有及时到场,面试官叫不到人就会过号处理。第一次过号的应聘者会被排到下一位,第二次过号则会排队下两位,第三次过号则会被安排到下四位。以此类推,按2^x的次序计算步长,过号次数越多则排队越后,直至队尾。也有人因为某些原因需要优先面试,优先面试的人会被提前叫号,如果优先面试的人未及时到场,则取消优先面试资格,按约定规则处理。 请写一段程序,实现以上排队叫号功能。 输入描述 每行输入1个应聘者预约消息,依次为应聘者编号、姓名、是否优先面试(true是,false 否)、预约顺序(整数1至1000)、过号次数(整数 0 至10),最后一行以Exit结束。 输出描述 从第1个人开始叫号,输出所有被叫到的应聘者信息,格式为编号:姓名:

By Ne0inhk