题目来源于leetcode,解法和思路仅代表个人观点。传送门。
难度:简单
用时:00:20:00(出了个小意外,总体来说比较简单)
题目
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1
/ \ / \
2 3 2 3
[1,2,3], [1,2,3]
输出: true
示例 2:
输入: 1 1
/ \
2 2
[1,2], [1,null,2]
输出: false
示例 3:
输入: 1 1
/ \ / \
2 1 1 2
[1,2,1], [1,1,2]
输出: false
思路
看到题目的时候,感觉不愧是简单题,立马就有思路了。
- 可以先按照一定的规则记录其中一棵树。
- 再遍历另一棵树,看是否满足。
如何记录一棵树的结构?
根据满二叉树的结构,可以知道,
- 如果一个节点的id为n(从1开始编号),则其左孩子节点的id为2*n,其右孩子节点的id为2*n+1。那么我们可以用一个长度为2m-1的一维数组,来保存其结构。(其中,m为二叉树深度)
但是,这样两点比较难处理。
(1)二叉树的深度需要先遍一次树,才能知道。
(2)所需要保存的空间太大了。
所以我们可以简化一下,在遍历这棵树的时候,用Map结构保存二叉树的编号和节点的值。
代码
/**
* 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 {
Map<Integer,Integer> treeMap = new HashMap<>();
public boolean isSameTree(TreeNode p, TreeNode q) {
//把其中一个树转换成特定的结构,然后存起来map
convertToMap(p,1);
//依次查找另一棵树是否满足这个结构
return checkTree(q,1);
}
public boolean checkTree(TreeNode node,int id){
if(node == null){
if(treeMap.get(id) == null){
return true;
}else{
return false;
}
}
Integer temp = treeMap.get(id);
if(temp != null && temp == node.val){
return checkTree(node.left,2*id) && checkTree(node.right,2*id+1);
}else{
return false;
}
}
public void convertToMap(TreeNode node,int id){
if(node == null){
return;
}
treeMap.put(id,node.val);
convertToMap(node.left,2*id);
convertToMap(node.right,2*id+1);
}
}
官方提供的优法算法
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;
} else {
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
}
算法复杂度
时间复杂度: O(q+min(p,q))。其中,q为一颗树的节点数,p为另一棵树的节点数。官方算法为O(min(p,q))。
空间复杂度: O(q)。其中,q为一颗树的节点树。官方算法为O(min(p,q))。