递归算法

【算法导论】贪心算法,递归算法,动态规划算法总结

主宰稳场 提交于 2020-02-23 10:26:55
一般实际生活中我们遇到的算法分为四类: 一>判定性问题 二>最优化问题 三>构造性问题 四>计算性问题 而今天所要总结的算法就是着重解决 最优化问题 《算法之道》对三种算法进行了归纳总结,如下表所示: 标准分治 动态规划 贪心算法 适用类型 通用问题 优化问题 优化问题 子问题结构 每个子问题不同 很多子问题重复(不独立) 只有一个子问题 最优子结构 不需要 必须满足 必须满足 子问题数 全部子问题都要解决 全部子问题都要解决 只要解决一个子问题 子问题在最优解里 全部 部分 部分 选择与求解次序 先选择后解决子问题 先解决子问题后选择 先选择后解决子问题 分治算法特征: 1)规模如果很小,则很容易解决。//一般问题都能满足 2)大问题可以分为若干规模小的相同问题。//前提 3)利用子问题的解,可以合并成该问题的解。//关键 4)分解出的各个子问题相互独立,子问题不再包含公共子问题。 //效率高低 【一】动态规划: 依赖:依赖于有待做出的最优选择 实质:就是分治思想和解决冗余。 自底向上(每一步,根据策略得到一个更小规模的问题。最后解决最小规模的问题。得到整个问题最优解) 特征:动态规划任何一个i+1阶段都仅仅依赖 i 阶段做出的选择。而与i之前的选择无关。但是动态规划不仅求出了当前状态最优值,而且同时求出了到中间状态的最优值。 缺点:空间需求大。 【二】贪心算法: 依赖

【算法导论】贪心算法,递归算法,动态规划算法总结

痴心易碎 提交于 2020-02-23 10:24:55
一般实际生活中我们遇到的算法分为四类: 一>判定性问题 二>最优化问题 三>构造性问题 四>计算性问题 而今天所要总结的算法就是着重解决 最优化问题 《算法之道》对三种算法进行了归纳总结,如下表所示: 标准分治 动态规划 贪心算法 适用类型 通用问题 优化问题 优化问题 子问题结构 每个子问题不同 很多子问题重复(不独立) 只有一个子问题 最优子结构 不需要 必须满足 必须满足 子问题数 全部子问题都要解决 全部子问题都要解决 只要解决一个子问题 子问题在最优解里 全部 部分 部分 选择与求解次序 先选择后解决子问题 先解决子问题后选择 先选择后解决子问题 分治算法特征: 1)规模如果很小,则很容易解决。//一般问题都能满足 2)大问题可以分为若干规模小的相同问题。//前提 3)利用子问题的解,可以合并成该问题的解。//关键 4)分解出的各个子问题相互独立,子问题不再包含公共子问题。 //效率高低 【一】动态规划: 依赖:依赖于有待做出的最优选择 实质:就是分治思想和解决冗余。 自底向上(每一步,根据策略得到一个更小规模的问题。最后解决最小规模的问题。得到整个问题最优解) 特征:动态规划任何一个i+1阶段都仅仅依赖 i 阶段做出的选择。而与i之前的选择无关。但是动态规划不仅求出了当前状态最优值,而且同时求出了到中间状态的最优值。 缺点:空间需求大。 【二】贪心算法: 依赖

二分查找算法的递归与非递归实现(C++)

*爱你&永不变心* 提交于 2020-02-22 21:17:48
二分查找 又称 折半查找 , 首先, 假设表中元素是按升序排列, 将 表 中间位置 的关键字与查找关键字比较: 如果两者相等, 则查找成功; 否则利用中间位置将表分成前、 后两个子表: 如果中间位置的关键字大于查找关键字, 则进一步查找前一子表 否则进一步查找后一子表 重复以上过程, 直到找到满足条件的记录, 使查找成功, 或直到子表不存 在为止, 此时查找不成功。 二分查找算法的递归实现 //如果找到target,返回其所在数组下标,如果未找到,返回-1; int binary_search ( std :: vector < int > & sort_array , int begin , int end , int target ) { if ( begin > end ) { return - 1 ; } int mid = ( begin + end ) / 2 ; if ( target == sort_array [ mid ] ) { return mid ; } else if ( target < sort_array [ mid ] ) { return binary_search ( sort_array , begin , mid - 1 , target ) ; } else if ( target > sort_array [ mid ] ) {

转:一文学会递归解题

独自空忆成欢 提交于 2020-02-22 15:53:40
前言 递归是算法中一种非常重要的思想,应用也很广,小到阶乘,再在工作中用到的比如统计文件夹大小,大到 Google 的 PageRank 算法都能看到,也是面试官很喜欢的考点 最近看了不少递归的文章,收获不小,不过我发现大部分网上的讲递归的文章都不太全面,主要的问题在于解题后大部分都没有给出相应的时间/空间复杂度,而时间/空间复杂度是算法的重要考量!递归算法的时间复杂度普遍比较难(需要用到归纳法等),换句话说,如果能解决递归的算法复杂度,其他算法题题的时间复杂度也基本不在话下。另外,递归算法的时间复杂度不少是不能接受的,如果发现算出的时间复杂度过大,则需要转换思路,看下是否有更好的解法 ,这才是根本目的,不要为了递归而递归! 本文试图从以下几个方面来讲解递归 什么是递归? 递归算法通用解决思路 实战演练(从初级到高阶) 力争让大家对递归的认知能上一个新台阶,特别会对递归的精华:时间复杂度作详细剖析,会给大家总结一套很通用的求解递归时间复杂度的套路,相信你看完肯定会有收获 什么是递归 简单地说,就是如果在函数中存在着调用函数本身的情况,这种现象就叫递归。 以阶乘函数为例,如下, 在 factorial 函数中存在着 factorial(n - 1) 的调用,所以此函数是递归函数 public int factorial ( int n ) { if ( n < = 1 ) {

第四章 递归算法 1209:分数求和

扶醉桌前 提交于 2020-02-22 03:00:35
1209:分数求和 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 4743 通过数: 2670 【题目描述】 输入n个分数并对他们求和,并用最简形式表示。所谓最简形式是指:分子分母的最大公约数为1;若最终结果的分母为1,则直接用整数表示。 如:56、103均是最简形式,而36需要化简为12,31需要化简为3。 分子和分母均不为0,也不为负数。 【输入】 第一行是一个整数n,表示分数个数,1≤n≤10; 接下来n行,每行一个分数,用"p/q"的形式表示,不含空格,p,q均不超过10。 【输出】 输出只有一行,即最终结果的最简形式。若为分数,用"p/q"的形式表示。 【输入样例】 2 1/2 1/3 【输出样例】 5/6 思路:公约数 和公倍数 # include <iostream> # include <cstdio> using namespace std ; int n , p [ 10001 ] , q [ 10001 ] , gbs = 1 , totfz ; int gcd ( int a , int b ) { return b ? gcd ( b , a % b ) : a ; } int lcm ( int a , int b ) { return a * b / gcd ( a , b ) ; } int main ( ) { cin >>

Java数据结构与算法->递归

感情迁移 提交于 2020-02-21 11:25:26
递归 递归设计思路 1.找重复 (子问题) 2.找重复中的变化量 -> 参数 3.找参数变化趋势 -> 设计出口 换句话说就是把一个任务划一刀分成两份,自己做一部分,委托别人做另外一部分。 练习策略 1.循环改递归 2.经典递归 3.大量练习,总结规律,掌握套路 递归的定义 1.自身调用自身 public class Main { public static void main ( String [ ] args ) { function ( 10 ) ; } static void function ( int i ) { if ( i == 0 ) { //退出递归的条件 return ; } function ( i - 1 ) ; //自身调用自身 } } 练习 求n*(n-1)的阶乘 public class Main { public static void main ( String [ ] args ) { f1 ( 10 ) ; } /* * f1(n):求n的阶乘 --> 求n-1的阶乘 * 找重复:n*(n-1)的阶乘,求(n-1)是问题的重复 * 找变化:变化的量应该作为参数 * 找边界:出口 */ static int f1 ( int n ) { if ( n == 1 ) { return 1 ; //因为1的阶乘就是1 } return n * f1

基础知识概要

家住魔仙堡 提交于 2020-02-20 19:29:21
1.算法复杂度——O记号,Ω符号,θ符号 T(n)=O(f(n)) iff c>0,当 n足够大时,有T(n)<c*f(n)T(n)=Ω(f(n)) iff c>0,当 n足够大时,有T(n)>c*f(n)T(n)=θ(f(n)) iff c1c2>0,当 n足够大时,有c1*f(n)>T(n)>c2*f(n) 2.复杂度类型 1)常数复杂度——O(1):效率最高 2)对数复杂度——O(logn):lnN,lgN,log,这类算法非常有效,复杂度无限接近于常数,logN=O(N^c) 3)多项式复杂度——O(n^c): 4)线性复杂度——O(n):所有O(n)类函数 5)指数复杂度——O(a^n):这类算法计算成本增长极快,通常被认为不可忍受 3.复杂度分析的主要方法: 迭代:级数求和 递归:递归跟踪+递推方程 猜测+验证 4.封底估算 1天=24hr*60min*60sec=25*4000=10^5sec 一生=一世纪=100yr*365=3*10^4day=3*10^9sec 三生三世=10^10sec 5.迭代和递归 计算任意n个整数之和 迭代:int sum=0;//O(1)for(int i=0;i<n;i++)//O(n) sum+=A[i];O(1) return sum;O(1)递归:return (n<1)?0:sum(A,n-1) +A[n-1]

PHP无限级分类的递归算法

蓝咒 提交于 2020-02-20 19:23:21
至少需要3个字段 第一个是主键(ID),第二个是父级分类ID(parentid),第三个是分类的名称(classname)。可能的一种效果是: ID PARENTID CLASSNAME 1 0 一级分类A 2 0 一级分类B 3 1 二级分类A 4 1 二级分类B 主要思路:首先看第三行和第四行,父类ID(PARENTID)的值是1,表示属于id=1这个类的子类,而,一,二两行因为是一级分类,没有上级分类,所以父类ID(PARENTID)的值是0,表示初级分类,依次类推便实现了无限级分类。最终的效果是: ├一级分类A ├─┴二级分类A ├─┴二级分类B ├一级分类B 然后就是程序,这里以PHP作为描述语言,可以很方便的改成其他语言,因为原理相似,就是一个递归而已。 <?php $dbhost = "localhost"; // 数据库主机名 $dbuser = "root"; // 数据库用户名 $dbpd = "123456"; // 数据库密码 $dbname = "test"; // 数据库名 mysql_connect($dbhost,$dbuser,$dbpd); //连接主机 mysql_select_db($dbname); //选择数据库 mysql_query("SET NAMES 'utf8'"); display_tree("├",0); function

java动手动脑3

霸气de小男生 提交于 2020-02-20 02:15:39
2016-10-152016-10-15一.编写一个方法,使用以上算法生成指定数目(比如1000个)的随机整数。 生成50个1到10的随机整数。 value=a+(int)(Math.Random()*b) 生成a到b的随机整数 JOptionPane.showMeaasgeDialog(null;output,".....") 弹出框题目 二.代码MethodOverLoad有什么特殊之处? 使用了同一种方法但是是不同类型。这是“方法重载”,构成重载的条件:1.方法名相同(square)2.参数类型不同(int,double),参数个数不同或参数类型的顺序不同。 三. (1)使用组合数公式利用n!计算。 (2)使用递推的方法用杨辉三角形计算 (3)使用递归的方法用组合数递推公式计算 四.递归编程解决汉诺塔问题。 五.使用递归方式判断某个字符是否是回文。(panlindrom) 来源: https://www.cnblogs.com/cxr0711/p/5964921.html

KO递归之汉诺塔---C语言

馋奶兔 提交于 2020-02-19 04:13:31
汉诺塔: 汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 单看这个问题描述有点让人抓瞎,这是当然,无论多么简单的问题描述,在没有建立具体地模型之前都是让人不知所云的,仅仅用生活中的语言去描述一些数学或算法问题往往会让听者产生理解偏差, 这也和每个的理解能力和思维方式有很大关系,这就显示出数学的强大了,数学让问题不再模糊,参数和公式组成的模型让问题不再有理解偏差和误区,只可惜数学没学好,看来以后还得回来把高数、概率论这些给补回来。 说了一些题外话,下面来对汉诺塔问题进行解释和建立模型 这是示意图,a是起始柱,c是目标柱,b起到中转作用 在进行转移操作时,都必须确保大盘在小盘下面,且每次只能移动一个圆盘,最终c柱上有所有的盘子且也是从上到下按从小到大的顺序。 很多时候看到这些蛋疼和矫情操作就觉得数学家真是思维清奇、智慧如海,嗯还有吃饱了撑的,某兄台邪魅地一笑,道:直接把c和a交换位置不就行了,我想这位兄台以后或成大器或被人打死。 问题看起来并不复杂,当a柱子上只有一个盘子时只要把那个盘子直接移到c就行了, 有两个盘子的话把1号盘先移到b柱,在把2号盘移到c柱