1。先假设有一个可以解决子问题的方法(这个方法也就是总的方法) 2。把解决子问题的方法代入到解决整个问题中来,分别解决总问题对应的下一级的几个子问题中来 3。思考总的这个问题要怎么解决好这些已经分别解决好的各自子问题的子问题(有点绕)4。想好终止条件,也就是下文的base case
public TreeNode reverseBinaryTree(TreeNode root){//1下面的2处也是1
//先处理base case,当root ==null 时,什么都不需要做,返回空指针
if(root == null){//4
return null;
}
else{
//把左子树翻转
TreeNode left = reverseBinaryTree(root.left);//2
//把右子树翻转
TreeNode right = reverseBinaryTree(root.right);//2
//把左右子树分别赋值给root节点,但是是翻转过来的顺序
root.left = right;//3
root.right = left;//3
//返回根节点
return root;
}
}
例题 翻转二叉树
这道题是一个经典的题目,Mac上著名软件HomeBrew的作者曾经在面试Google的时候被问到了,还没做出来,因此最后被拒。。。。于是他在个人推特上抱怨到:
Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
最后大家的关注点就慢慢从作者被拒本身转移到了题目上了。。。那我们看看这道题到底有多难。
翻转前
翻转后
看起来好像很麻烦的样子,每个子树本身都被翻转一遍。但是我们使用分治的思维,假如说我们有个函数,专门翻转二叉树的。假如我们把B子树翻转好,再把C子树翻转好,那么我们要做的岂不就是简单的把A节点的左赋给C(原来是B),再把A节点的右赋给B(原来是C)。这个问题是不是就解决了?
对于B和C我们可以用同样的分治思维去递归解决。用一段代码来描述一下
public TreeNode reverseBinaryTree(TreeNode root){
//先处理base case,当root ==null 时,什么都不需要做,返回空指针
if(root == null){
return null;
}
else{
//把左子树翻转
TreeNode left = reverseBinaryTree(root.left);
//把右子树翻转
TreeNode right = reverseBinaryTree(root.right);
//把左右子树分别赋值给root节点,但是是翻转过来的顺序
root.left = right;
root.right = left;
//返回根节点
return root;
}
}
根据这个例子,再加上中序打印的题目,我们应该已经可以很轻松的理解到了,对于二叉树的题目或者算法,分而治之
和 递归
的核心思想了,就是把左右子树分开处理,最后在把结果合并(把处理好的左右子树对应根节点进行处理)。
作者:qing的世界
链接:https://www.jianshu.com/p/6f179f37ad79
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。