递归
将一个大问题分解成多个和大问题逻辑相同的子问题
递归出口(边界条件)----TLE /RE 找全递归终止条件 ---经验
递归代码的理解:画递归调用图-带一个比较小的值进去,你手动画一下它的执行和返回过程
从哪个地方调用就返回到哪里

怎么写一个递归函数:确定递归函数是干什么的,在写代码的过程中,只考虑当前的问题
怎么解决,不分析下层的递归怎么展开
递归函数用来解决这些类似的小问题的----->确定递归函数能解决什么问题
在写递归函数时,当我们需要用到类似小问题的答案的时候,直接调用递归函数
汉诺塔问题:归纳,找规律

n时,可以把上面n-1个盘子看成一个整体
此时 一:把n-1个盘子从A移动到B,C当作媒介-----递归
二: n-1 B C A
递归函数:4个参数 (盘子数量x,起点柱子s,终点柱子e ,媒介柱子h) x个盘子---->s---h---->e
错误案例:

//错误:1.没有递归出口 2.start和end放着起不了任何作用,应该用个数n
3.引用传参,修改不了A,C
正确:
void move(int s,int e,int h,int n) A C B n
{ //递归出口 :当只有一个盘子时直接放到e
if(n==1) move n s---->e; return;
move(A,B,C,n-1);
move n s---->e ;
move(B,C,A,n-1);
}
递归和动态规划,分治的区别: 最优子结构(可以分解成若干个小问题)
1.递归不是算法,是一种编程技巧,很多算法(只要满足最优子结构)都可以用递归来写
2.动态规划和分治
动态规划具有最优子结构(可以分解成若干个小问题) 和 重叠子问题的特点 也就是说分成的每个小问题之间不是相互独立的,
求解小问题3需要用到小问题1和小问题2的答案
而分治:也具有最优子结构 但是小问题之间独立, 并且小问题之间的处理逻辑也不一定相同
总结:相同之处是都具有最优子结构特点
如果小问题存在重叠,或者处理逻辑都是一样的---->动态规划
如果小问题的处理逻辑不完全相同,那相同的可以写个递归代码,不同的单独给它写一个函数或代码
也就是说解决一个题目可能要你自己写三个函数
分治


分治法来做:


cpp
class Solution {
public:
int tanxin(vector<int>& nums,int l,int r,int mid)
{
//start = nums[mid];
/*
//找以mid为右边界,左边的最大值
res = 0; p = 0;
for (int i = mid - 1; i >= l; i--)
{
p += nums[i];
res = max(res, p);
}
start += res;
//找以mid为左边界,右边的最大值
res = 0, p = 0;
for (int i = mid+1; i<=r; i++)
{
p += nums[i];
res = max(res, p);
}
start += res;
*/
//错啦,懂什么叫做横跨吗?左边和右边至少要有一个数据...那么就不要start,直接求左右最大值
int lval= INT_MIN; //保证至少能取到一个值
int p = 0;
for (int i = mid; i >= l; i--)
{
p += nums[i];
lval = max(lval, p);
}
int rval = INT_MIN;
p = 0;
for (int i = mid+1; i<=r; i++)
{
p += nums[i];
rval = max(rval, p);
}
return rval + lval;
}
int fenzhi(vector<int>& nums,int l,int r)
{
if (l == r) return nums[l]; //递归出口
int mid = (l + r) / 2;
//拆分成l~mid,mid+1~r
int lans = fenzhi(nums, l, mid);
int rans = fenzhi(nums, mid + 1, r);
//横跨的情况单独写个函数
int mans = tanxin(nums,l,r,mid);
return max(max(lans, rans), mans);
}
//返回连续子数组的最大值
int maxSubArray(vector<int>& nums) { //
return fenzhi(nums, 0, nums.size() - 1);
}
};
动态规划来做:

cpp
class Solution {
public:
int dp[100005]; //以下标i结尾的连续子数组的最大和是
//降维优化: dp[n]只与dp[n-1]有关
int dp;
//不论哪个序列都是以数组nums中的数结尾的
int maxSubArray(vector<int>& nums) {
dp=nums[0];
int ans=nums[0];
for(int i=1;i<nums.size();i++)
{
dp=dp>0?dp+nums[i]:nums[i];
ans=max(dp,ans);
}
return ans;
}
}