递归算法

递归

时光总嘲笑我的痴心妄想 提交于 2020-03-07 19:14:42
1.递归的概念 递归就是方法自己调用自己,每次调用时传入不同的变量 2.递归能解决什么样的问题 1.各种数学问题如:8皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子的问题(google编程大赛); 2.各种算法中也会用到递归,比如快排,归并排序,分治算法等; 3.将用栈解决的问题->递归代码比较简洁 3.递归要遵守的重要规则 1.执行一个方法时,就创建一个新的受保护的独立空间(栈空间); 2.方法的局部变量是独立的,不会相互影响; 3.如果方法中使用的是引用类型变量(比如数组),就会引用该引用类型数据; 4.递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError; 5.当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,改方法也就执行完毕. 4.递归小案例 package com . itguigu . recursion ; public class RecursionTest { public static void main ( String [ ] args ) { test ( 4 ) ; int res = factorial ( 4 ) ; System . out . println ( "res=" + res ) ; } // 打印问题 public static

二分法查找算法 (递归)

眉间皱痕 提交于 2020-03-06 21:45:23
有一由小到大排列的数组m[],数组大小为n,请用二分法查找算法找出与关键数key相等的元素,若查找成功返回元素在数组中的位置,没找到返回-1. 1 // 二分查找.cpp 2 3 #include "stdafx.h" 4 #include <string> 5 6 int search(int m[],int key,int low,int high) 7 { 8 int mid=(low+high)/2; 9 if (low>high) 10 return -1; 11 if (key==m[mid]) 12 return mid; 13 else if (key<m[mid]) 14 return search(m,key,low,mid-1); 15 else 16 return search(m,key,mid+1,high); 17 } 18 19 void main() 20 { 21 int a[]={1,2,5,7,9,12,16}; 22 int i,len; 23 len=sizeof(a)/sizeof(a[0])-1; 24 i=search(a,12,0,len); 25 printf("%d\n",i); 26 } 来源: https://www.cnblogs.com/xingele0917/archive/2012/10/04/2711628

vivo一面凉经

爷,独闯天下 提交于 2020-03-06 18:30:41
链接: https://www.nowcoder.com/discuss/112192 目录 1.手撕代码,二分查找,递归非递归 2.java反射机制,优点缺点 3.java线程同步,synchronized锁升级机制,synchronized lock区别 4.项目,感觉最难的一点,怎么解决之类的 5.看成绩单,问我成绩为什么比较差 6.java public private protected default 7.手撕代码,中序遍历,递归非递归 8.学校的一堆事,什么社团经历,最有成就感的事,最失败的事,优点缺点啥的 1.手撕代码,二分查找,递归非递归 采用非递归方式完成二分算法 public static int binarySearch(Integer[] srcArray,int des){ int low=0; int high=srcArray.length-1; while(low<=high){ int middle=(low+high); if(des==srcArray[middle]) return middle; else if(des<srcArray[middle]){ high=middle-1; }else{ low=middle+1; } } return -1; } 采用递归方式完成二分查找算法 int BinSearch(int Array[

快速排序

 ̄綄美尐妖づ 提交于 2020-03-06 12:32:34
快速排序(QuickSort) 划分的关键是要求出基准记录所在的位置pivotpos,编程时候的关键点 快速排序: 既然能把冒泡KO掉,马上就激起我们的兴趣,tnd快排咋这么快,一定要好好研究一下。 首先上图: 从图中我们可以看到: left指针,right指针,base参照数。 其实思想是蛮简单的,就是通过第一遍的遍历(让left和right指针重合)来找到数组的切割点。 第一步:首先我们从数组的left位置取出该数(20)作为基准(base)参照物。 第二步:从数组的right位置向前找,一直找到比(base)小的数, 如果找到,将此数赋给left位置(也就是将10赋给20), 此时数组为:10,40,50,10,60, left和right指针分别为前后的10。 第三步:从数组的left位置向后找,一直找到比(base)大的数, 如果找到,将此数赋给right的位置(也就是40赋给10), 此时数组为:10,40,50,40,60, left和right指针分别为前后的40。 第四步:重复“第二,第三“步骤,直到left和right指针重合, 最后将(base)插入到40的位置, 此时数组值为: 10,20,50,40,60,至此完成一次排序。 第五步:此时20已经潜入到数组的内部,20的左侧一组数都比20小,20的右侧作为一组数都比20大, 以20为切入点对左右两边数按照

八大排序(三)-------快速排序

蹲街弑〆低调 提交于 2020-03-06 08:59:47
快速排序法介绍: 快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 感觉自己能力并不足以将一个问题,或算法讲解的足够清楚,只是在别人的基础上理解,明白了代码的含义,知道了执行的流程,知道了原理,但是要我自己讲述,或者深入的说出其底层原理,做不来 所以很多内容粗糙且模糊,见谅 所以这下面的是我参考的别人的讲解,来源忘了 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列。 3 1 2 5 4 6 9 7 10 8 在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。想一想,你有办法可以做到这点吗? 给你一个提示吧。请回忆一下冒泡排序,是如何通过“交换”

递归算法

℡╲_俬逩灬. 提交于 2020-03-05 19:55:21
直接或间接调用函数本身,则该函数称为递归函数。 舍得舍得,有舍才有得。 递归递归,有递才有归。 递归,先确定终止条件或者说是出口。当参数为何值时,递归结束,之后直接把结果返回。注意,确定出口时前几个数可能不能用规律得出,需要一 一确定下来。 再根据不同的条件进行变化,即找出函数的等价关系式。 举一个简单例子 Fibonacci具体 : int fib ( int n ) { if ( n <= 1 ) return 1 ; return fib ( n - 1 ) + fib ( n - 2 ) ; } 再举个经典例子阶乘 int f ( int n ) { if ( n == 0 ) return 1 ; else return n * f ( n - 1 ) ; } 实际上递归虽然看似很精简,实际效率很低,时间复杂度可达到O(2^N )。 递归调用实际上是函数自己在调用自己,而函数的调用开销是很大的,系统要为每次函数调用分配存储空间,并将调用点压栈予以记录。而在函数调用结束后,还要释放空间,弹栈恢复断点。所以说,函数调用不仅浪费空间,还浪费时间。 ——作者:Clemente 链接:https://www.jianshu.com/p/7a10b0221964 来源: CSDN 作者: 恋霏雨 链接: https://blog.csdn.net/z2431435/article

二叉树遍历的递归与非递归实现(python)

只愿长相守 提交于 2020-03-05 16:32:31
最近在刷leetcode时,刷到了二叉树中序遍历的题目,所以特在此记录一下,下面我将给出中序遍历的递归实现和非递归(迭代)实现的代码与算法思想: 1. 中序遍历的递归实现: 1 class TreeNode(object): 2 def __init__(self, x): 3 self.val = x # 节点存储的值 4 self.left = None # 左子节点 5 self.right = None # 右子节点 6 7 class solution: 8 def __init__(self): 9 self.__result_list = list() # 存放中序遍历结果的集合 10 def inorder_traversal(self, root : TreeNode) -> list: 11 if root == None: return # 判断节点是否为空 12 self.inorder_traversal(root.left) # 递归遍历左子树 13 self.__result_list.append(root.val) # 将节点的值存放到集合中 14 self.inorder_traversal(root.right) # 递归遍历右子树 15 return self.__result_list # 返回集合 递归实现的算法思想:先中序遍历左子树

1、算法初识

痴心易碎 提交于 2020-03-05 12:42:10
1.什么是 算法 ? 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。 也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。 如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。 不同的算法可能用不同的时间、空间或效率来完成同样的任务。 一个算法的优劣可以用空间复杂度与时间复杂度来衡量。 算法中的指令描述的是一个计算,当其运行时能从一个初始状态和(可能为空的)初始输入开始,经过一系列有限而清晰定义的状态,最终产生输出并停止于一个终态。 一个状态到另一个状态的转移不一定是确定的。随机化算法在内的一些算法,包含了一些随机输入。 1.1特征 一个算法应该具有以下五个重要的特征: 有穷性 (Finiteness) 算法的有穷性是指算法必须能在执行有限个步骤之后终止; 确切性 (Definiteness) 算法的每一步骤必须有确切的定义; 输入项 (Input) 一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定出了初始条件; 输出项 (Output) 一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的; 可行性 (Effectiveness) 算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作步

oracle中 connect by prior 递归算法

[亡魂溺海] 提交于 2020-03-04 07:25:12
http://blog.163.com/xxciof/blog/static/7978132720095193113752/ oracle中 connect by prior 递归算法 Oracle中start with...connect by prior子句用法 connect by 是结构化查询中用到的,其基本语法是: select ... from tablename start with 条件1 connect by 条件2 where 条件3; 例: select * from table start with org_id = 'HBHqfWGWPy' connect by prior org_id = parent_id; 简单说来是将一个树状结构存储在一张表里,比如一个表中存在两个字段: org_id,parent_id那么通过表示每一条记录的parent是谁,就可以形成一个树状结构。 用上述语法的查询可以取得这棵树的所有记录。 其中: 条件1 是根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。 条件2 是连接条件,其中用PRIOR表示上一条记录,比如 CONNECT BY PRIOR org_id = parent_id就是说上一条记录的org_id 是本条记录的parent_id,即本记录的父亲是上一条记录。 条件3 是过滤条件

省选模拟37 题解

点点圈 提交于 2020-03-04 00:03:21
A. Alchemy 考虑递归挪动这个塔的过程。 然后发现有一些递归是没有必要的。 通过初始状态可以判断递归的前半部分或后半部分是没有必要的。 直接统计不递归的部分的贡献,然后递归另一部分就好了。 这样的复杂度应该可以做到线性。 B. Algebra 要统计这个答案无非两个办法。找到 $n$,判断在两个进制下的和是否相等。 找到两个进制下相等的数,然后取交集找到 $n$。 采用后一种办法。 考虑首先写一个函数 $next(n,k,s)$ 表示 $\geq n$ 的 $k$ 进制下总和为 $s$ 的最小的数字。 这个函数写一个类似数位 dp 的东西就可以 $O(log n)$ 求出来。 然后设 $g_s$ 表示 $s$ 的答案至少为 $g_s$。 那么每次取出最小的 $g_s$,通过 $next(g_s,a,s),next(g_s,b,s)$ 的取值,可以判断是否找到答案。 如果没有找到答案,那么更新 $g_s$ 。 C. Anarchy 暴力的做法是枚举$x,y$,然后计算两点之间的距离。 然而这个算法不是很好优化,考虑现在枚举 $x$ 和 $y-x$。 也就是说枚举爆炸点和爆炸向量,然后可以更新对应的 $y$。 这样的话问题可以写成一个卷积的形式 $ans_y=\sum \limits_{i \oplus j=y}a_i*dis_j$。 $\oplus$