数据结构与算法之递归、循环、动态规划、回溯
- 递归:代码简洁,但是效率低(每次函数调用都有时间和空间的开销);
- 循环:和递归相反;
斐波那契数列(剑指offer---面试题9)
题目:写入一个函数,输入n,求斐波那契(Fibonacci)数列的第n项,斐波那契数列的定义:f(n) = f(n-1) + f(n-2),初始值f(0)=0且f(1)=1;
解题思路:
(1)递归:根据f(n)的定义来递归计算;
(2)循环:定义三个长整数one、Two和Res,迭代计算;
合并两个排序的链表(剑指offer---面试题17)
详情见“链表”专栏:递归;
树的子结构(剑指offer---面试题18)
详情见“树”专栏:递归;
二叉树的镜像(剑指offer---面试题19)
详情见“树”专栏:递归;
二叉搜索树的后续遍历序列(剑指offer---面试题24)
详情见“树”专栏:递归;
二叉树中和为某一值的路径(剑指offer---面试题25)
详情见“树”专栏:递归、回溯;
字符串的排列(剑指offer---面试题28)
详情见“字符串”专栏:递归、回溯;
连续子数组的最大和(剑指offer---面试题31)
详情见“数组”专栏:动态规划;
二叉树的深度(剑指offer---面试题39)
详情见“树”专栏:递归;
矩阵中的路径(剑指offer---面试题66)
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向上、下、左、右移动一格,如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。比如下图3×4的矩阵中包含一条字符串"bcced"的路径,但矩阵中不包含字符串"abcb"的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子;
a b c e
s f c s
a d e e
- bool HasPath(char *matrix, int rows, int cols, char *str);
解题思路:回溯法,构建二维数组visited记录格子是否已经被访问过;
(1)初始化visited全部为false,从数组matrix的每个结点开始判断从当前结点开始是否包含字符串,即调用HasPathCore(matrix, rows, cols, row, col, str, index, visited);
(2)HasPathCore首先判断row/col是否越界、当前格子的字符是否和str中第index字符相等、visited中当前格子是否第一次访问;
(3)若步骤2满足条件,则从当前格子开始向上、下、左、右四个方向开始继续判断,即递归调用HasPathCore;
(4)若四个方向有一个判断就返回true,若都不满足则返回false,且回退visited和index;
机器人的运动范围(剑指offer---面试题67)
题目:地上有一个m行n列的方格,一个机器人从坐标(0,0)的格子开始移动,它每一次可以向上、下、左、右移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。例如当k为18时,机器人能够进入方格(35,37),因为3+5+3+7=18,但它不能进入方格(35,38),因为3+5+3+8=19。请问该机器人能够到达多少个格子?
- int MovingCount(int threshold, int rows, int cols);
解题思路:回溯法,构建二维数组visited记录格子是否已经被访问过;
(1)初始化visited全部为false,调用MovingCountCore(threshold, rows, cols, row, col, visited)开始判断能够进入的格子数目,其中row = 0、col = 0;
(2)MovingCountCore首先判断row/col是否越界、是否满足条件threshold;
(3)若步骤2满足条件,则从当前格子开始向上、下、左、右四个方向开始继续判断,即递归调用MovingCountCore;
(4)返回结果1 + MovingCountCore(row-1,col) + MovingCountCore(row+1,col) + MovingCountCore(row, col-1) + MovingCountCore(row,col+1)或者0;