leetcode [Same Tree]

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    //写递归算法只用考虑到怎么分,只用考虑最表面的一块,剩下的如何递归的只用设计好递归出口即可
    public boolean isSameTree(TreeNode p, TreeNode q) {
        //递归出口
        if(p == null && q != null) return false;
        if(p != null && q == null) return false;
        if(p == null && q == null) return true;
        if(p.val != q.val) return false;//p、q都不为空的情况
        //递归
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

代码优化:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
	//写递归算法只用考虑到怎么分,只用考虑最表面的一块,剩下的如何递归的只用设计好递归出口即可
    public boolean isSameTree(TreeNode p, TreeNode q) {
    	
        /*if(p == null && q != null) return false;
        if(p != null && q == null) return false;
        if(p == null && q == null) return true;*/
    	
        //递归出口
    	//上面注释这一块可以用下面这一行解决
    	if(p == null || q == null) return p == q;
    	
    	if(p.val != q.val) return false;
        //递归
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

解法二(非递归):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
    	/*
    	 * 先写算法思路,再写代码
    	 * 用两个队列来存放两棵二叉树的结点,非空结点才放入队列中
    	 * 类似于层次遍历,两个队列从队首弹出一个结点时,比较两个弹出的结点的左右子结点的内容,
    	 * 然后再将两个结点的左右非空子结点分别放入两个队列中
    	 */
    	Queue<TreeNode> P = new LinkedList<TreeNode>();
    	Queue<TreeNode> Q = new LinkedList<TreeNode>();
    	if(p == null || q == null) return p == q;
    	if(p.val != q.val) return false;
        //根结点要是非空的
       P.add(p);
    	Q.add(q);
    	while(!P.isEmpty() &&!Q.isEmpty()){
    		p = P.poll();
    		q = Q.poll();
    		if(p.left == null && q.left != null) return false;
    		if(p.left != null && q.left == null) return false;
    		//两个弹出结点的左子结点都为空时不管
    		if(p.left != null && q.left != null){
    			if(p.left.val == q.left.val){
    				P.add(p.left);
    				Q.add(q.left);
    			}
    			else{
    				return false;
    			}
    		}
    		
    		if(p.right == null && q.right != null) return false;
    		if(p.right != null && q.right == null) return false;
    		//两个弹出结点的右子结点都为空时不管
    		if(p.right != null && q.right != null){
    			if(p.right.val == q.right.val){
    				P.add(p.right);
    				Q.add(q.right);
    			}
    			else{
    				return false;
    			}
    		}
    	}
    	return P.size() == Q.size();
    }
}

解法二(非递归)代码优化:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
    	/*
    	 * 先写算法思路,再写代码
    	 * 用两个队列来存放两棵二叉树的结点,非空结点才放入队列中
    	 * 类似于层次遍历,两个队列从队首弹出一个结点时,比较两个弹出的结点的左右子结点的内容,
    	 * 然后再将两个结点的左右非空子结点分别放入两个队列中
    	 */
    	Queue<TreeNode> P = new LinkedList<TreeNode>();
    	Queue<TreeNode> Q = new LinkedList<TreeNode>();
    	if(p == null || q == null) return p == q;
    	if(p.val != q.val) return false;
    	P.add(p);
    	Q.add(q);
    	while(!P.isEmpty() &&!Q.isEmpty()){
    		p = P.poll();
    		q = Q.poll();
    		if(p.val != q.val) return false;
    		
    		if(p.left != null) P.add(p.left);
    		if(q.left != null) Q.add(q.left);
    		//比上面的解法二巧妙的方法,不用判断p、q的子结点是否为空,是否忽略,
    		//放入队列后通过队列P和Q的长度是否相等来判断两棵树的这一部分结构是否相同,因为都只判断了左子结点,队列长度要么加0要么加1
    		if(P.size() != Q.size()) return false;//return P.size() == Q.size()这种写法不对,直接返回了下面的代码永远不会执行
    		
    		if(p.right != null) P.add(p.right);
    		if(q.right != null) Q.add(q.right);
    		//比上面的解法二巧妙的方法,不用判断p、q的左子结点是否为空,是否忽略,
    		//放入队列后通过队列P和Q的长度是否相等来判断两棵树的这一部分结构是否相同,因为都只判断了右子结点,队列长度要么加0要么加1
    		if(P.size() != Q.size()) return false;
    	}
    	return P.size() == Q.size();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值