目录
在计算机科学中,递归是一种重要的概念和技术。它允许函数直接或间接地调用自身,以解决复杂的问题。
递归的基本思想是将一个大问题分解成若干个较小的、相似的子问题,然后通过不断地递归调用自身来解决这些子问题,直至达到基本情况。
递归在许多领域都有广泛的应用,如算法设计、数据结构处理等。它可以帮助我们更简洁、优雅地解决一些原本复杂的问题。
一、递归函数的编写
对于一个递归函数,我们可以把它分为三部分:函数头、函数主体、递归出口;分别思考每一部分如何设计即可!
二、题目练习
1、汉诺塔----点击跳转题目
完整代码;
class Solution {
public:
//将x柱子上最上面的n个盘子借助y柱子转移到z柱子上
void dfs(vector<int>& x,vector<int>& y,vector<int>& z,int n)
{
if(n == 1)
{
z.push_back(x.back());
x.pop_back();
return ;
}
dfs(x,z,y,n-1);
z.push_back(x.back());
x.pop_back();
dfs(y,x,z,n-1);
}
void hanota(vector<int>& A, vector<int>& B, vector<int>& C)
{
dfs(A,B,C,A.size());
}
};
2、合并两个有序链表---点击跳转题目
本题可以循环解决,主要研究如何递归解决,循环方法不过多叙述
代码:
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2)
{
if(!list1) return list2;
if(!list2) return list1;
ListNode* ret;
if(list1->val < list2->val)
{
ret = list1;
list1 = list1->next;
ret->next = mergeTwoLists(list1,list2);
}
else
{
ret = list2;
list2 = list2->next;
ret->next = mergeTwoLists(list1,list2);
}
return ret;
}
};
3、反转链表----点击跳转题目
本题也可以用循环解决(创捷一个虚拟头节点,遍历链表不断对虚拟头节点做头插操作)
递归如何解决呢?
代码:
class Solution {
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;
}
};
通过上面的题目练习,是不是对递归更加熟悉与了解了呢?其实在编写和理解递归函数时,我们要把递归函数当成一个能一定完成任务的黑盒,坚定不移的相信它可以完成它的使命,我们只需在递归函数中在合适的时机自信的调用它即可!
下一篇博客,会继续通过算法题来练习递归,敬请期待.....