最近在刷leedcode, 发现很多题目是一类,有共同的解法和思路,所以就打算总结一下,因为我是新手,题目难度先从easy开始,后面会陆续补充. 这一篇是关于TREE的总结
Leedcode-100-Same Tree:
问题:Given two binary trees, write a function to check if they are equal or not.
Two binary trees are considered equal if they are structurally identical and the nodes have the same value.(就是给两颗树,判断是否相等.)
解题思路:遍历两个树,判断每个node是否相等.思路很简单但是,我们需要注意什么叫做相等,这里题目定义为结构上完全相等并且每一个node上的value相等,这里需要指出的是p=q 是判断地址相等,p.val = p.val是判断value相等;
代码实现:
Solution1: 递归
public class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null) return true; //遍历到最底层 只是指满足这个条件返回true 并不带表如果这个条件不成立返回flase
else if(p == null || q == null) return false;//不能对空指针操作,如果不写,会报错比如p=[],q=[0]
// if(p == null || q == null) return(p==q) 前两句可以合成一句
else if(p.val != q.val) return false; //判断值是否相等
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right); //递归
}
}
Solution2: 迭代(BSP)
public class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null || q == null) return p == q;
ArrayDeque<TreeNode> queue1 = new ArrayDeque();
ArrayDeque<TreeNode> queue2 = new ArrayDeque();
queue1.add(p);
queue2.add(q);
while(!queue1.isEmpty() && !queue2.isEmpty()){
TreeNode x = queue1.remove();
TreeNode y = queue2.remove();
if(x.val != y.val) return false;
if(x.left != null) queue1.add(x.left);
if(y.left != null) queue2.add(y.left);
if(queue1.size() != queue2.size()) return false;
if(x.right != null) queue1.add(x.right);
if(y.right != null) queue2.add(y.right);
if(queue1.size() != queue2.size()) return false;
}
return queue1.size() == queue2.size();
}
}
这里面需要注意的是如何防止空指针出现异常,空指针是不能用来操作的,如果操作了会抛出空指针异常的错误;第一次写迭代的时候,不知道怎么去判断空指针,一直在判断x.left与y.left还有x.right和y.right之间个null的关系,很麻烦并且难以理清楚.后来才发现可以利用队列的size来判断,非常简单明了和清晰.
Leedcode-101-Symmetric Tree
问题:Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree [1,2,2,3,4,4,3]
is symmetric:
1 / \ 2 2 / \ / \ 3 4 4 3But the following
[1,2,2,null,3,null,3]
is not:
1 / \ 2 2 \ \ 3 3解题思路:可以借鉴上一题的思路.只不过上一题是左左和右右相等,这一次判断的是两个子树左右是否相等.
Solution1 (递归):
public class Solution {
public boolean isSymmetric(TreeNode root) {
TreeNode x = root;
if(x == null) return true;
ArrayDeque<TreeNode> queue1 = new ArrayDeque<TreeNode>();
ArrayDeque<TreeNode> queue2 = new ArrayDeque<TreeNode>();
if(x.left != null) queue1.add(x.left);
if(x.right != null)queue2.add(x.right);
if(queue1.size() != queue2.size()) return false;
while(!queue1.isEmpty() && !queue2.isEmpty()){
TreeNode x1 = queue1.remove();
TreeNode x2 = queue2.remove();
if(x1.val != x2.val) return false;
if(x1.left != null) queue1.add(x1.left);
if(x2.right != null) queue2.add(x2.right);
if(queue1.size() != queue2.size()) return false;
if(x1.right != null) queue1.add(x1.right);
if(x2.left != null) queue2.add(x2.left);
if(queue1.size() != queue2.size()) return false;
}
return queue1.size() == queue2.size();
}
}
Solution 2(递归);
public class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true; //注意这里,要是空的,后面就不可以操作.
return isSymmetric(root.left, root.right)
}
private boolean isSymmetric(TreeNode x, TreeNode y){
if(x == null || y == null) return x == y;
else if(x.val != y.val) return false;
return isSymmetric(x.left,y.right) && isSymmetric(x.right,y.left);
}
}
总结:这两道题思路,解法几乎都一模一样,来总结一下具体思路和重点.
思路:判断两个树是否想等(或者一个树是否对称),我们需要做的是遍历两个树中的每一个节点,然后判断value是否相等.
方法:迭代(DSP或者BSP,这里我采用的是BSP)或者递归;
解题要点:如何确定相等?value相等就可以;但是这里面我们需要考虑一个重要的问题,就是空指针问题,如果x不为空,但是x的子节点空的,我们不能对子节点进行任何操作,如果操作了会报空指针异常的错误.比如,我们已知x和y的value相等,但是x和y的子节点有一个或者两个都是空,下面的操作会报错:
if(x.val == y.val) {
if(x.right.val == y.right.val) return true; // 如果x.right和y.righ都是null,进行这个操作会报错
}
else return false;
这里是我们需要注意的;
在递归中我们利用这个条件语句来判断空节点的存在:
if(x == null || y == null) return x == y;
在迭代中我们利用队列的size来判断:
if(x1.left != null) queue1.add(x1.left);
if(x2.right != null) queue2.add(x2.right);
if(queue1.size() != queue2.size()) return false;
if(x1.right != null) queue1.add(x1.right);
if(x2.left != null) queue2.add(x2.left);
if(queue1.size() != queue2.size()) return false;