226.翻转二叉树
1.思路
递归与迭代都可用,优先掌握递归法!
按照题目所示,翻转就是对当前节点的左右子树进行位置交换,并且一直按照此模式。
可以采用前序或后序遍历,要位置交换的是当前节点的左右子树,引入第三方变量来交换。
2.注意
1.不能采用中序遍历,中序遍历可能会将子树交换两次;
2.交换的是当前节点的左右子树,所以交换方法传入参数是每一次的当前节点。
3.代码实现
class Solution {
public TreeNode invertTree(TreeNode root) {
pretrans(root);
return root;
}
public void pretrans(TreeNode root){
if(root==null){
return;
}
//使用前序遍历
swap(root);
pretrans(root.left);
pretrans(root.right);
}
public void swap(TreeNode root){
TreeNode temp;
temp=root.left;
root.left=root.right;
root.right=temp;
}
}
101.对称二叉树
1.思路
要判断以根节点分开两边子树是否对称,可以按照两棵树一起遍历去判断,以根节点左右子树分别为两颗树同时遍历,判断当前节点的左外侧与右外侧,左内侧与右内侧是否相等。
2.注意:
1.两树是同时遍历的!
2.最后对左右内侧外侧是否全都相等判断,要返回两者共同成立,也就是说对两者判断要用&&。
3.代码实现
class Solution {
public boolean isSymmetric(TreeNode root) {
return judge(root.left,root.right);
}
public boolean judge(TreeNode node1,TreeNode node2){
if(node1!=null&&node2==null){
return false;
}else if(node1==null&&node2!=null){
return false;
}else if(node1==null&&node2==null){
return true;
}else if(node1.val!=node2.val){
return false;
}
boolean outside=judge(node1.left,node2.right);
boolean inside=judge(node1.right,node2.left);
//要共同成立
return outside&&inside;
}
}
4.相关题目推荐
这两道题目基本和本题是一样的,只要稍加修改就可以AC。
100.相同的树
思路:基本上是同判断是否对称是相同的,只是此题判断的相同位置不一样,把位置进行改变就好。
实现代码:
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null){
return true;
}else if(p==null||q==null){
return false;
}else if(p.val!=q.val){
return false;
}
boolean leftp=isSameTree(p.left,q.left);
boolean rightq=isSameTree(p.right,q.right);
return leftp&&rightq;
}
}
572.另一个树的子树
思路:此题有几种解法,看过题解后使用到了树哈希和KMP算法,难度有点大,所以用了时间复杂度较高的逐个匹配。基本上也是同以上一样,但是此题需要在包含另外一棵树的大树里面进行代码所示的一些判断。
实现代码:
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
return dfs(root,subRoot);
}
public boolean dfs(TreeNode root,TreeNode subRoot){
if(root==null){
return false;
}
return judge(root,subRoot)||dfs(root.left,subRoot)||dfs(root.right,subRoot);
}
public boolean judge(TreeNode root,TreeNode subRoot){
if(root==null&&subRoot==null){
return true;
}else if(root==null||subRoot==null){
return false;
}else if(root.val!=subRoot.val){
return false;
}
boolean left=judge(root.left,subRoot.left);
boolean right=judge(root.right,subRoot.right);
return left&&right;
}
}
102.二叉树的层序遍历
可以将层序遍历代码理解后作为一个模板,很多题目都可以按照此模板进行一些逻辑的改变就可以完成!!!
1.思路
层序遍历是从上到下从左到右的方式去遍历的,借助队列存树节点,在队列长度大于0时,一层一层的出列,再将出列的节点值存入集合中,然后判断出列的节点对应的左右节点是否为空,不为空就加入到队列中,要注意当出列后将记得将队列长度进行减1,最后在这层节点出队列完了后再将每层遍历的集合加入大集合中。
2.注意
1.在每一个节点出列后,记得要相应的对队列长度减一。
3.代码实现
class Solution {
List<List<Integer>> res=new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
find(root);
return res;
}
public void find(TreeNode node){
if(node==null){
return;
}
Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.offer(node);
while(!queue.isEmpty()){
List<Integer> list=new ArrayList<>();
int len=queue.size();
while(len>0){
TreeNode no=queue.poll();
int value=no.val;
list.add(value);
if(no.left!=null){
queue.offer(no.left);
}
if(no.right!=null){
queue.offer(no.right);
}
len--;
}
res.add(list);
}
4.相关题目推荐
以下题目都可以以层序遍历迭代法为模板写出:
102.二叉树的层序遍历
107.二叉树的层次遍历II
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度
111.二叉树的最小深度