文章目录

  • 分治策略和递归
  • 分治策略的步骤
  • 示例1:阶乘问题
  • 示例2:打印数组的值
  • 示例3:在数组中查找目标值

分治策略和递归

分治策略:
是将规模比较大的问题可分割成规模较小的相同问题。问题不变,规模变小。 这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
递归:
若一个函数直接地或间接地调用自己,则称这个函数是递归的函数。(简单地描述为“自己调用自己”)。分治法所能解决的问题一般具有以下四个特征:

  1. 该问题的规模缩小到一定的程度就可以容易地解决。
  2. 该问题可以分解为若干个规模较小的相同问题。
  3. 使用小规模的解,可以合并成该问题原规模的解。
  4. 该问题所分解出的各个子规模是相互独立的。

分治策略的步骤

在分治策略中递归地求解一个问题,在每层递归中应用如
下三个步骤:

  1. 分解︰将问题划分成一些子问题,子问题的形式与原问题一样,只是规模更小。
  2. 解决︰递归地求解子问题。如果子问题的规模足够小,则停止递归,直接求解。
  3. 合并︰将小规模的解组合成原规模问题的解。

如何理解?
示例:
需要数一堆硬币的个数,如果有一百枚硬币,一个人数需要很短时间,但如果是一亿个硬币,一个人不可能数完。分治策略就是把数这堆硬币的问题分解,分给几万人去数,这样问题本质没有改变,只是规模变小了,在每个人数完后,把结果合并,就完成了原来问题的解。

示例1:阶乘问题

题目:输入一个整数n,求n的阶乘

分析:通过规律可以得知可以定义为这样的函数,此时,fac(n - 1)代表从1乘到n - 1的阶乘。

循环写法:

int fac(int n)
{int sum = 1;for (int i = 1; i <= n; ++i){sum *= i;}return sum;
}

递归写法:

 int fac(int n)
{if (n <= 1)return 1;elsereturn fac(n - 1) * n;
}

他们的区别就是:
循环的时间复杂度为:O(n),空间复杂度为:S(1)
而递归的时间复杂度和空间复杂度为: O(n), S(n). 因为在递归过程中,每次递归都是调用函数自己,所以每次都需要再次开辟栈帧,对于空间的开销大。并且如果在循环中写错了控制条件,程序并不会崩溃,如果递归的终止条件错误,那么会导致栈溢出。

示例2:打印数组的值

示例:

int main(void)
{int nums[] = { 12,23,34,45,56,67,78 };int numsSize = sizeof(nums) / sizeof(nums[0]);Print_nums(nums, numsSize);return 0;
}

循环写法:

void Print_nums(const int* nums, int numsSize)
{if (nums == nullptr) return;for (int i = 0; i < numsSize; ++i){cout << nums[i] << " ";}cout << endl;
}

递归写法:

void Print(const int* nums, int numsSize)
{if (numsSize > 0){Print(nums, numsSize - 1);cout << nums[numsSize - 1] << " ";}
}
void Print_nums(int* nums, int numsSize)
{if (nums == nullptr || numsSize < 1) return;Print(nums, numsSize);cout << endl;
}

对于递归过程的讲解:
实际上递归函数运行时分为两个过程,递推和回归。

图示:
红色线为递推过程,绿色线为回归过程。

示例3:在数组中查找目标值

示例3:在数组中查找目标值,存在则返回下标,不存在返回-1.

int main(void)
{int nums[] = { 12,23,34,45,56,67 };int numsSize = sizeof(nums) / sizeof(nums[0]);int target = 45;int pos = findTarget(nums, numsSize, target);cout << pos << endl;return 0;
}

循环写法:

int findTarget(const int* nums, int numsSize, int target)
{if (nums == nullptr || numsSize < 1) return -1;int pos = numsSize - 1;while (pos >= 0 && nums[pos] != target){--pos;}return pos;
}

递归写法:

int Find(const int* nums, int numsSize, int target)
{if (numsSize <= 0 || nums[numsSize - 1] == target)return numsSize - 1;elsereturn Find(nums, numsSize - 1, target);
}
int findTarget(const int* nums, int numsSize, int target)
{if (nums == nullptr || numsSize < 1) return -1;return Find(nums, numsSize, target);
}

算法:分治策略和递归1 | 通过迭代来学习递归相关推荐

  1. c语言递归最小值,递归求最大最小值算法 分治策略(c语言实现)

    思路:运用分治的思想,将要排序的整个数组从中间劈开,分别求其左右两边的最大最小值,然后将求出的最大最小值合起来进行比较. 当左右两边的数组小到一定程度时: (1)数组中只有一个元素,maxNum=mi ...

  2. 【算法设计与分析】16 分治策略:快速排序(快速排序的时间复杂度计算)

    上一篇文章学习了:[算法设计与分析]15 分治策略:芯片测试 文章目录 1. 快速排序的基本思想 1.2 时间复杂度的计算 1.21 最坏情况时间复杂度计算 1.22 最好情况时间复杂度 1.23 平 ...

  3. 回溯法之递归回溯和迭代回溯

      回溯法有通用解题法之称,它可以系统的搜索一个问题的所有解或者任意解.它在问题的解空间树中,按深度优先策略从根节点出发搜索解空间树,算法搜索至解空间树的任意一个结点时,先判断该节点如(子树)是否包含 ...

  4. java迭代和 递归的异同_Java中的递归和迭代之间有什么区别?

    该递归和迭代都重复执行的指令集.递归是指函数中的语句重复调用自身时的情况.该迭代是当循环重复执行,直到控制条件为假.递归和迭代之间的主要区别在于,递归是一个过程,始终应用于函数,而迭代则应用于我们要重 ...

  5. 递归:我不用栈 非递归:栈使我快乐

    偶尔敲代码,今天看树的遍历方式递归和非递归方式实现,碰到了一个关于栈的问题. 栈 栈的定义:栈是限定仅在表头进行插入和删除操作的线性表.要搞清楚这个概念,首先要明白"栈"原来的意思 ...

  6. 算法设计与分析第2章 递归与分治策略

    第2章 递归与分治策略 2.1 递归算法 递归算法:直接或间接地调用自身的算法. 递归函数:用函数自身给出定义的函数.两个要素:边界条件.递归方程 优点:结构清晰,可读性强,而且容易用数学归纳法来证明 ...

  7. 计算机算法设计与分析之----- 递归与分治策略

    递归与分治策略 [Master定理] 快速排序 优化 逆序对(归并算法) 火柴排队[NOIP2013 提高组] 集合求和 方法一: 递归 (2^n ) 方法二: 组合数学知识 [HNOI2008]越狱 ...

  8. 算法设计与分析——递归与分治策略——最接近点对问题

    [问题描述] 最近对问题要求在包含有n个点的集合S中,找出距离最近的两个点.设 p1(x1,y1),p2(x2,y2),--,pn(xn,yn)是平面的n个点. 严格地将,最近点对可能不止一对,此例输 ...

  9. 算法设计与分析——递归与分治策略——全排列

    算法设计与分析--递归与分治策略--全排列 全排列问题的解决是通过分治与递归思想来解决的 首先判断是否递归到了最后一位,如果递归到了最后一位,则输出他当前的全排列序列. 如果没有到达最后一位,则循环的 ...

最新文章

  1. centos 配置bond_Linux CentOS 7 多网卡配置bond模式 bond1 bond5 bond6
  2. 学会感恩会使你回报的更多!
  3. python 同时打乱多个列表
  4. Java集合之ArrayList源码解析
  5. mysql中Bname表示什么_《MY SQL实用教程》期末考试题
  6. CentOS系统如何搭建离线yum源
  7. JVM怎么判断对象是否存活
  8. 作为开发,你对进程和线程能否区分开来呢?
  9. 郭明錤:新款iPhone S或为“有史以来最便宜的5G iPhone”
  10. 我用系统的思想来编程
  11. linux 小度 驱动_小度 WiFi 与 Windows 和 Linux
  12. “去中心化”到底是什么?
  13. 报错 mysql 1194
  14. Java 接收OutLook 微软邮箱邮件
  15. 电脑只能上qq,但是不能打开网页的…
  16. CSS 网页定位与布局
  17. 证明:1/n调和级数为何是发散的
  18. python培训机构 马哥
  19. C# 微信证书签名,WECHATPAY2-SHA256-RSA2048 签名方式
  20. n9006 android6,超详细三星Note3(N9006)ROOT教程

热门文章

  1. 03、【电脑维修】防火墙丢失,找不到 windows firewall服务, windows defender firewall服务被禁用或防火墙无法打开
  2. 6个usb口服务器无响应,USB插口无反应怎么办?USB接口不能用解决办法
  3. [Phonegap+Sencha Touch] 移动开发71 Sencha项目开发、调试方法建议
  4. 如何从Excel表格导入数据批量生成二维码
  5. STM8 8位基本型定时器 TIM4
  6. Android ImageView 图片拉伸,填满控件
  7. 【信号与系统】(二)信号与系统概述——基本信号
  8. Innovus——数据准备和验证
  9. Windows 找不到 gpedit.msc
  10. 即将升级的LDK7.1支持云授权了