递归的模式--自顶向下调用
1.递归结束条件
2.递归调用
3.每一层执行的内容
4.返回
27二叉树的镜像
思路:
1.递归结束条件:节点为空,返回自己
2.递归调用:变量暂存结果,防止递归途中改变了结构
3.每一层执行的内容:交换左右节点
4.返回:返回左右调换后的节点
代码:
public TreeNode mirrorTree(TreeNode root) {
if(root==null)return null;
TreeNode leftChild=mirrorTree(root.right);
TreeNode rightChild=mirrorTree(root.left);
root.left=leftChild;
root.right=rightChild;
return root;
}
28对称的二叉树
思路:
对称的条件:
- 特例:空树是对称的
- 非空树要满足:
- 左右子节点对称,要满足
- 对称节点 值相同
- 对称节点下一层两组对称节点 也对称
- 左右子节点对称,要满足
代码思路:
对称节点的概念是递归的,而不是某棵树递归,因此要另写一个判断对称节点的函数来调用。
public boolean isSymmetricNode(TreeNode leftNode,TreeNode rightNode){
if(leftNode==null&&rightNode==null){//左右节点同时为空,则这对节点 对称
return true;
}
else if(leftNode!=null&&rightNode!=null){//左右节点同时不为空,需要后续判断
if((leftNode.val==rightNode.val) &&//值相等
(isSymmetricNode(leftNode.left,rightNode.right))&&//下一层两对结点分别对称
(isSymmetricNode(leftNode.right,rightNode.left))){
return true;
}
else {//左右节点有一个不为为空,则这对节点 不对称
return false;
}
}
else {
return false;
}
}
public boolean isSymmetric(TreeNode root) {
if (root==null)return true;
return isSymmetricNode(root.left,root.right);//左右节点是否对称
}
55I二叉树的深度
思路:
递归求解二叉树的深度
1.空节点,返回深度0
2.返回当前节点对应数的深度=max(当前节点左子树深度,当前节点右子树深度)+1;
public int maxDepth(TreeNode root) {
if(root==null)return 0;
return (Math.max(maxDepth(root.left),maxDepth(root.right))+1);
54二叉搜索树求第k大节点
思路:
二叉搜索树中序(左根右)输出为递增序列
改为右根左则为递减序列
中序遍历递归代码思路:
1.空节点则返回
2,递归右节点
3. 将根存入集合
4. 递归左节点
5. 结束
调用函数:
根据下标获取集合中的数
class Solution {
List<Integer>list=new ArrayList<Integer>();
public void fillList(TreeNode root){
if(root==null)return ;
fillList(root.right);
list.add(root.val);
fillList(root.left);
}
public int kthLargest(TreeNode root, int k) {
fillList(root);
return list.get(k-1);
}
}
55II平衡二叉树
二叉树平衡的条件
任意节点的左右子树的深度相差不超过1
也就是满足:
- 两子树深度差不超过1
- 左右子树都是平衡二叉树
递归判断是否是平衡二叉树思路:
1.空树返回是
2.返回 左右子树深度差小于等于1 且 递归左树 且递归右树
public int maxDepth(TreeNode root) {
if(root==null)return 0;
return (Math.max(maxDepth(root.left),maxDepth(root.right))+1);
}
public boolean isBalanced(TreeNode root) {
if(root==null)return true;
return Math.abs(maxDepth(root.right)-maxDepth(root.left))<=1 &&
isBalanced(root.left)&&
isBalanced(root.right);
}
68二叉搜索树的最近公共祖先
思路:依据二叉树的性质
当前节点同时大于两个数则搜左树
同时小于则搜右树
若一大一小则说明两数在此分割 找到结果返回
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (true){
int val=root.val;
if(val>p.val&&val>q.val){
root=root.left;
}
else if(val< p.val&&val<q.val){
root=root.right;
}
else {
return root;
}
}
}
68II二叉树最近公共祖先
思路:深搜二叉树 找到节点时回溯将路径存入集合 根据两集合查找公共祖先
递归深搜思路:
全局变量 两个集合 一个布尔变量标志找到节点
1.若空树 返回
2.节点值相等 改变标记变量 当前节点存入集合
3.递归搜索左树
4.回溯时若标记找到则存入集合并返回(因为无需搜索另一个子树 所以返回)
5.递归搜索右树
6.回溯时若标记找到则存入集合并返回
7.若没找到 直接返回
List<TreeNode>pathOfP=new ArrayList<TreeNode>();
List<TreeNode>pathOfQ=new ArrayList<TreeNode>();
boolean isFind;
public void gnrPath(TreeNode root,TreeNode node,List<TreeNode> path){
if(root==null){return;}
if(node.val== root.val){
path.add(root);
isFind=true;
return;
}
gnrPath(root.left,node,path);
if (isFind) {
path.add(root);
return;
}
gnrPath(root.right, node,path);
if (isFind) {
path.add(root);
return;
}
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode ans=null;
isFind=false;
gnrPath(root, p, pathOfP);
isFind=false;
gnrPath(root, q, pathOfQ);
int pPos=pathOfP.size()-1;
int qPos=pathOfQ.size()-1;
for (; pPos >= 0 && qPos >= 0; pPos--, qPos--) {
int pVal=pathOfP.get(pPos).val;
int qVal=pathOfQ.get(qPos).val;
if(qVal==pVal){
ans= pathOfP.get(pPos);
}
else {
return ans;
}
}
return ans;
}