使用递归的条件:::?
**不用在头脑中模拟递归函数的调用**
宏观角度——“三步走”
1.明确递归函数的意义(传什么参数?返回什么结果?完成什么操作?);
2.充分相信这个递归函数;
3.将注意力集中在当前位置(节点)上,关注在当前位置的操作及边界条件。
例题
一、二叉树的最大深度
1.以树的根节点为输入,计算该树的最大深度;
2.充分相信这个递归函数;
3.当前位置节点操作:先得到左右子树的最大深度,再计算当前节点的最大深度
边界条件:遇到空树时,返回空树的深度为0.
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;//边界条件
int left = maxDepth(root -> left);
int right = maxDepth(root -> right);
return max(left,right) + 1;//当前节点操作
}
};
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root :
return 0
left = self.maxDepth(root.left)
right = self.maxDepth(root.right)
return max(left,right) + 1
二、二叉树展开为链表
1.以树的根节点为输入,将该树按先序遍历展开为单链表;
2.充分相信这个递归函数;
3.当前节点操作:先得到左右子树按先序遍历展开为链表的结果,再按照“根左右”的顺序进行拼接;
边界条件:遇到空树,直接返回
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;//边界条件
flatten(root -> left);
flatten(root -> right);
swap(root -> left,root -> right);//当前节点操作
TreeNode*p = root;
while(p -> right){
p = p -> right;
}
p -> right = root -> left;//拼接
root -> left = nullptr;
}
};
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root :
return
self.flatten(root.right)
self.flatten(root.left)
tmp = root.right
root.right = root.left
root.left = None
while root.right != None:
root = root.right
root.right = tmp
三、汉诺塔问题
1.将A上的所有圆盘借助B移动到C上面;
2.充分相信这个函数;
3.当前位置操作:先将A上除最大编号的圆盘全部借助C移动到B上,然后将A上剩余的圆盘移动到C上,最后将B上的所有圆盘借助A移动到C上;
边界条件:需要移出圆盘的柱子上没有圆盘
进一步具体化:
1.将A上的n个圆盘借助B移动到C上;
2.充分相信这个函数;
3.当前位置操作:先将A上的n-1个圆盘借助C移动到B上,再将A中剩余的圆盘移动到C上,最后将B上的n-1个圆盘借助A移动到C上;
边界条件:需要移出圆盘的柱子上没有圆盘。
class Solution:
def hanota(self, A: List[int], B: List[int], C: List[int]) -> None:
n = len(A)
self.move(n, A, B, C)
# 定义move 函数移动汉诺塔
def move(self,n, A, B, C):
if n == 1:
C.append(A[-1])
A.pop()
return
else:
self.move(n-1, A, C, B) # 将A上面n-1个通过C移到B
C.append(A[-1]) # 将A最后一个移到C
A.pop() # 这时,A空了
self.move(n-1,B, A, C) # 将B上面n-1个通过空的A移到C
四、停止原地的方案数


上图少一个参数。

增加cur来反映移动的状态。
1.在当前位置cur,剩余k次操作的情况下,指针最后停留在索引0的方案数;
2.充分相信这个函数;
3.当前位置操作:三种操作各进行一次,得到当前位置为cur-1(cur,cur+1),剩余k-1次操作的情况下,指针最后停留在索引0的方案数。将所有结果相加。
边界条件:不能再进行操作(K=0),指针达到数组边界(cur = 0,n-1)
class Solution{
public:
int f(int k,int n, int cur);
if(k == 0) return cur == 0;
if(cur == 0){
return f(k-1,n,cur)+f(k-1,n,cur+1);
}
if(cur == n-1){
return f(k-1,n,cur-1)+f(k-1,n,cur);
}
return f(k-1,n,cur)+f(k-1,n,cur-1)+f(k-1,n,cur+1)
int runWays(int k,int n){
return f(k,n,0)
}
}
1079

被折叠的 条评论
为什么被折叠?



