递归
(1)自己调用自己
(2)讲将一个问题拆解成解决方案完全相同的子问题
(3)必须有一个明确的终点
(4)到终点后计算结果原路返回
这里例举一个经典问题,斐波那契数https://leetcode.cn/problemset/?page=1&search=509
递归做法:
#include<iostream>
using namespace std;
class Solution {
public:
int fib(int n) {
if(n==0)return 0;
else if(n==1)return 1;
else return fib(n-2)+fib(n-1);
}
int main()
{
int n;
cin>>n;
cout<<fib(n)<<endl;
return 0;
}
};
矩阵算法:
当第一个数和第二个数为1时
就这么替换下去,可以得出
类似于斐波那契数的题:爬楼梯:https://leetcode.cn/problems/climbing-stairs/description/
因为一次能爬1 或 2级楼梯
(1)当只有一阶楼梯时,只有一种方法 1
(2)当有两阶楼梯时,有两种方法 1 1,2
(3)当有三阶楼梯时,如果我第一次迈一阶楼梯那就是1+(2)的步骤,如果我第一次迈二阶楼梯那就是2+(1)的步骤,也就是前两次步骤之和3
同理四阶楼梯是三阶楼梯+二阶楼梯步骤之和5
但是如果用递归会超时,所以我们利用滚动窗口思想,利用中间变量t实现优化
#include<iostream>
using namespace std;
class Solution {
public:
int climbStairs(int n) {
int a=0,b=1,t=0;
for(int i=1;i<=n;i++)
{
t=b+a;
a=b;
b=t;
}
return t;
}
int main()
{
int n;
scanf("%d",&n);
printf("%d",climbStairs(n));
return 0;
}
};
递归回溯
class Solution {
public:
vector<vector<int>>res;
void dfs(vector<int>&nums,int len,vector<int>&ans,int n,int vi[])
{
if(n==len){res.push_back(ans);return;}
for(int i=0;i<len;i++)
{
if(vi[i]!=1&& n<len)
{
vi[i]=1;
ans.push_back(nums[i]);
dfs(nums,len,ans,n+1,vi);
ans.pop_back();
vi[i]=0;
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<int>ans;
int vi[nums.size()];
memset(vi,0,sizeof(vi));
dfs(nums,nums.size(),ans,0,vi);
return res;
}
};
LCR 084. 全排列 II - 力扣(LeetCode)
递归回溯加去重
class Solution {
public:
vector<vector<int>>res;
map<vector<int>,int>mp;
void dfs(vector<int>& nums,int len,int n,int vi[],vector<int>&ans)
{
if(len==n){
mp[ans]++;
if(mp[ans]==1)
res.push_back(ans);
return;
}
for(int i=0;i<len;i++)
{
if(vi[i]==0)
{
vi[i]=1;
ans.push_back(nums[i]);
dfs(nums,len,n+1,vi,ans);
ans.pop_back();
vi[i]=0;
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
int vi[nums.size()];
memset(vi,0,sizeof(vi));
int n=0;
int len=nums.size();
vector<int>ans;
dfs(nums,len,n,vi,ans);
return res;
}
};
本文探讨了递归在编程中的应用,如斐波那契数列的递归实现,以及如何通过矩阵算法优化。同时介绍了爬楼梯问题的递归与滚动窗口解决方案,以及全排列问题的回溯算法和去重版本。
1499

被折叠的 条评论
为什么被折叠?



