算法:分治策略和递归1 | 通过迭代来学习递归
文章目录
- 分治策略和递归
- 分治策略的步骤
- 示例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 | 通过迭代来学习递归相关推荐
- c语言递归最小值,递归求最大最小值算法 分治策略(c语言实现)
思路:运用分治的思想,将要排序的整个数组从中间劈开,分别求其左右两边的最大最小值,然后将求出的最大最小值合起来进行比较. 当左右两边的数组小到一定程度时: (1)数组中只有一个元素,maxNum=mi ...
- 【算法设计与分析】16 分治策略:快速排序(快速排序的时间复杂度计算)
上一篇文章学习了:[算法设计与分析]15 分治策略:芯片测试 文章目录 1. 快速排序的基本思想 1.2 时间复杂度的计算 1.21 最坏情况时间复杂度计算 1.22 最好情况时间复杂度 1.23 平 ...
- 回溯法之递归回溯和迭代回溯
回溯法有通用解题法之称,它可以系统的搜索一个问题的所有解或者任意解.它在问题的解空间树中,按深度优先策略从根节点出发搜索解空间树,算法搜索至解空间树的任意一个结点时,先判断该节点如(子树)是否包含 ...
- java迭代和 递归的异同_Java中的递归和迭代之间有什么区别?
该递归和迭代都重复执行的指令集.递归是指函数中的语句重复调用自身时的情况.该迭代是当循环重复执行,直到控制条件为假.递归和迭代之间的主要区别在于,递归是一个过程,始终应用于函数,而迭代则应用于我们要重 ...
- 递归:我不用栈 非递归:栈使我快乐
偶尔敲代码,今天看树的遍历方式递归和非递归方式实现,碰到了一个关于栈的问题. 栈 栈的定义:栈是限定仅在表头进行插入和删除操作的线性表.要搞清楚这个概念,首先要明白"栈"原来的意思 ...
- 算法设计与分析第2章 递归与分治策略
第2章 递归与分治策略 2.1 递归算法 递归算法:直接或间接地调用自身的算法. 递归函数:用函数自身给出定义的函数.两个要素:边界条件.递归方程 优点:结构清晰,可读性强,而且容易用数学归纳法来证明 ...
- 计算机算法设计与分析之----- 递归与分治策略
递归与分治策略 [Master定理] 快速排序 优化 逆序对(归并算法) 火柴排队[NOIP2013 提高组] 集合求和 方法一: 递归 (2^n ) 方法二: 组合数学知识 [HNOI2008]越狱 ...
- 算法设计与分析——递归与分治策略——最接近点对问题
[问题描述] 最近对问题要求在包含有n个点的集合S中,找出距离最近的两个点.设 p1(x1,y1),p2(x2,y2),--,pn(xn,yn)是平面的n个点. 严格地将,最近点对可能不止一对,此例输 ...
- 算法设计与分析——递归与分治策略——全排列
算法设计与分析--递归与分治策略--全排列 全排列问题的解决是通过分治与递归思想来解决的 首先判断是否递归到了最后一位,如果递归到了最后一位,则输出他当前的全排列序列. 如果没有到达最后一位,则循环的 ...
最新文章
- centos 配置bond_Linux CentOS 7 多网卡配置bond模式 bond1 bond5 bond6
- 学会感恩会使你回报的更多!
- python 同时打乱多个列表
- Java集合之ArrayList源码解析
- mysql中Bname表示什么_《MY SQL实用教程》期末考试题
- CentOS系统如何搭建离线yum源
- JVM怎么判断对象是否存活
- 作为开发,你对进程和线程能否区分开来呢?
- 郭明錤:新款iPhone S或为“有史以来最便宜的5G iPhone”
- 我用系统的思想来编程
- linux 小度 驱动_小度 WiFi 与 Windows 和 Linux
- “去中心化”到底是什么?
- 报错 mysql 1194
- Java 接收OutLook 微软邮箱邮件
- 电脑只能上qq,但是不能打开网页的…
- CSS 网页定位与布局
- 证明:1/n调和级数为何是发散的
- python培训机构 马哥
- C# 微信证书签名,WECHATPAY2-SHA256-RSA2048 签名方式
- n9006 android6,超详细三星Note3(N9006)ROOT教程
热门文章
- 03、【电脑维修】防火墙丢失,找不到 windows firewall服务, windows defender firewall服务被禁用或防火墙无法打开
- 6个usb口服务器无响应,USB插口无反应怎么办?USB接口不能用解决办法
- [Phonegap+Sencha Touch] 移动开发71 Sencha项目开发、调试方法建议
- 如何从Excel表格导入数据批量生成二维码
- STM8 8位基本型定时器 TIM4
- Android ImageView 图片拉伸,填满控件
- 【信号与系统】(二)信号与系统概述——基本信号
- Innovus——数据准备和验证
- Windows 找不到 gpedit.msc
- 即将升级的LDK7.1支持云授权了