分治&递归

递归

将一个大问题分解成多个和大问题逻辑相同的子问题

递归出口(边界条件)----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的答案

而分治:也具有最优子结构 但是小问题之间独立, 并且小问题之间的处理逻辑也不一定相同

总结:相同之处是都具有最优子结构特点

如果小问题存在重叠,或者处理逻辑都是一样的---->动态规划

如果小问题的处理逻辑不完全相同,那相同的可以写个递归代码,不同的单独给它写一个函数或代码

也就是说解决一个题目可能要你自己写三个函数

分治

例题1:53. 最大子数组和 - 力扣(LeetCode)

分治法来做:

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;
}
}
相关推荐
飞Link8 小时前
什么是 AirSim?一文读懂无人机仿真平台
python·算法·无人机
zhangrelay8 小时前
新版|-|单片机原理与接口技术-2026持续改进优化-从MEGA2560-ESP32与Wokwi到ROS2-Lyrical与具身智能栈
笔记·单片机·嵌入式硬件·学习
Jimmy9 小时前
深夜突袭:我们的午夜战场
笔记·产品·电子书
xiaoye-duck10 小时前
《C++ 工具库实战》gflags 命令行参数解析库详解
c++·第三方库
一去不复返的通信er10 小时前
贪心算法-合并区间(LeetCode 56)
算法·leetcode·贪心算法
狂奔的sherry10 小时前
C++ 宏生成访问函数的代价:访问权限、调试和类型检查
c++·宏·编译·预处理器·类型检查
Shaoshing11 小时前
LeetCode100 49. 字母异位词分组
java·算法
志尊宝11 小时前
AI原生前端开发(025):端侧AI实战项目:智能笔记助手
人工智能·笔记·ai-native
YFJ_mily11 小时前
第二届区块链技术与基础模型国际学术会议(BTFM2027)
算法·区块链·能源·智能系统·rdlink研发家·机器人自动化