需要借助遍历的题型
题目一:翻转二叉树
思路:前中后序都可以
注意:中序遍历特别注意:在遍历左子树的时候,是传root.left的,因为,你上一步交换了左右指针,看代码一下就明白了
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
//每个结点的左右孩子反转就可以:中序遍历不行(改进的话:遍历右子树时候,传入的应该是左指针指向的孩子,因为上一步把左右指针交换了)
if(root==null) return root;
invertTree(root.left);
swapChildren(root);//左右指针交换了,所以下面传明面上的left,实质上的right
//要传root,不能传引用,否则它会变成孩子
invertTree(root.left);
return root;
}
public void swapChildren(TreeNode root){
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
}
}
题目二:对称二叉树
思想:
看左右子树,左边的4和右边的4,左边的3和右边的3,
结论:
左子树的left孩子和右子树的right孩子相等
左子树的right孩子和右子树的left孩子相等
所以左右子树一起遍历,不过关系要对应:
left.left和right.right
left.right和right.left
代码
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null) return true;
return compare(root.left,root.right);
}
//比较的左右子树的内外两侧,所以一起遍历
public boolean compare(TreeNode left,TreeNode right){
//镜像对比
//base
if(left==null&&right==null) return true;
if(left==null&&right!=null) return false;
if(left!=null&&right==null) return false;
//两个结点是否对称(不能省略...后面的是比较他们的子树是否对称)
if(left.val!=right.val) return false;
//子树是否对称
boolean leftCom=compare(left.left,right.right);
boolean rightCom=compare(left.right,right.left);
boolean isSame=leftCom&&rightCom;
return isSame;
}
}
题目三:左叶子结点和(可以用变量,也可以用树形dp,它的本质就是遍历)
首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。
左叶子的明确定义:如果左节点不为空,且左节点没有左右孩子,那么这个节点的左节点就是左叶子
思路:
左子树的,右子树的左叶子之和加上本结点的左叶子和=总和
注意:这道题也是经典的类树形dp,但是类树形dp本质也是递归,只是把递归的信息封装到一个结构了,后面会写
我们先看遍历的代码
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
//只有一个字段的info直接用变量代替
//root的左结点不为null,且左结点的左右孩子是null,它就是左叶子
if(root==null) return 0;
int leftsum=sumOfLeftLeaves(root.left);
int rightsum=sumOfLeftLeaves(root.right);
//本结点的左叶子和等于孩子的加自己的
int curleftsum=leftsum+rightsum;
if(root.left