Open azl397985856 opened 2 years ago
树的问题还是递归,一层层的。 比较每一个节点,感觉还是要想好节点是否为空的判断就好了
public boolean isSameTree(TreeNode p, TreeNode q) {
if (q==null&&p==null){
return true;
}else if(q==null||p==null){
return false;
}
if(p.val==q.val) {
boolean sameTree1 = isSameTree(p.left, q.left);
boolean sameTree = isSameTree(p.right, q.right);
return sameTree&&sameTree1?true:false;
}
return false;
}
复杂度分析 -时间复杂度:O(N) -空间复杂度:O(N)
树的遍历,然后比较当前节点的值是否相等和此节点的左右结构是否一样即可。
Java Code:
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
boolean ans = false;
if (p.val == q.val) ans = true;
boolean left = isSameTree(p.left, q.left);
boolean right = isSameTree(p.right, q.right);
return ans && left && right;
}
}
复杂度分析
令 n 为数组长度。
https://leetcode.com/problems/same-tree/
/**
* 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 boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null){
return true;
}
if(p == null || q == null){
return false;
}
return p.val == q.val && 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() {}
* 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 boolean isSameTree(TreeNode p, TreeNode q) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while(!queue.isEmpty()){
TreeNode a = queue.poll();
TreeNode b = queue.poll();
if(a == null && b == null){
continue;
}
if(a == null || b == null){
return false;
}
if(a.val != b.val){
return false;
}
queue.offer(a.left);
queue.offer(b.left);
queue.offer(a.right);
queue.offer(b.right);
}
return true;
}
}
dfs
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if not p and not q:
return True
if (not p and q) or (p and not q):
return False
if p.val!=q.val:
return False
return self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
时间复杂度: O(n)
空间复杂度: O(logn)
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
'''
if p and not q: return False
if not p and q: return False
if not p and not q: return True
if p.val != q.val: return False
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
'''
if not p and not q: return True
stack = []
stack.append((p,q))
while stack:
node1, node2 = stack.pop()
if not node1 and not node2:
continue
if node1 and node2 and node1.val == node2.val:
stack.append((node1.left, node2.left))
stack.append((node1.right, node2.right))
else:
return False
return True
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
先序遍历两棵树
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null) return true;
if(p == null || q == null) return false;
if(p.val != q.val){
return false;
}
else{
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
}
时间复杂度:$O(n)$
空间复杂度:$O(n)$
递归
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} p
* @param {TreeNode} q
* @return {boolean}
*/
var isSameTree = function(p, q) {
if (!p && !q) {
return true;
}
if (!p || !q) {
return false;
}
return p.val === q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
};
时间:O(N),其中 N 为树的节点数 空间:O(H),其中 H 为树的高度
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
'''
if not p and not q:
return True
if not p or not q:
return False
if p.val != q.val:
return False
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
'''
stack = []
stack.append((p,q))
while stack:
node1, node2 = stack.pop()
if not node1 and not node2:
continue
if node1 and node2 and node1.val == node2.val:
stack.append((node1.left, node2.left))
stack.append((node1.right, node2.right))
else:
return False
return True
Time complexity O(n) Space complexity Method I O(h), h是树的高度 Method 2 O(Q), Q不会超过相邻两层结点的最大值
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
# 若都为none
return True
if not p or not q:
# 若只有一个为none
return False
if p and q:
# 若两者都不为none
return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p && !q){
return true;
}
if(!p || !q){
return false;
}
return p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
if not p or not q:
return False
return p.val == q.val and self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
recursion,先保证当前的节点相同,再判断左右子树是否一致。
class Solution: def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if not p and not q:
return True
if p and not q:
return False
if not p and q:
return False
if p.val != q.val:
return False
else:
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
TC: O(N)
SC: O(H)
判断终止的条件,利用递归分别比较左右子树,注意 不能写if(p.val == q.val) return true;
例如:[1,2] 跟 [1,null,2]
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} p
* @param {TreeNode} q
* @return {boolean}
*/
var isSameTree = function(p, q) {
if(p == null && q == null) return true;
if(p == null || q == null) return false;
if(p.val !== q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
};
复杂度分析
主要考察数的遍历,数的遍历有二种方式,一种通过dfs【主要是递归的方式】,另一种则是bfs的方式,【这一点要注意的是,对某个节点进行判断是否相同的时候,需要对该节点的值进行判断,已经判断其左右孩子的值是否相等,如果不相等则直接返回false】
//通过递归的方式 class Solution { //树的题 一般都是对树的遍历, public boolean isSameTree(TreeNode p, TreeNode q) { if((p==null&&q!=null)||(p!=null&&q!=null&&q.val!=p.val)||(p!=null&&q==null)){ return false; }else if(p==null&&q==null)return true; return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right); } } //通过广度优先进行遍历 class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if(p==null && q == null)return true; if(p==null || q == null)return false; Queue<TreeNode> queue_p = new LinkedList<>(); Queue<TreeNode> queue_q = new LinkedList<>(); TreeNode temp_p,temp_q; queue_p.offer(p); queue_q.offer(q); while(!queue_q.isEmpty()&&!queue_p.isEmpty()){ int index_p=queue_p.size(); int index_q=queue_q.size(); if(index_p!=index_q)return false; while(index_p>0){ temp_p = queue_p.poll(); temp_q = queue_q.poll(); if((temp_p.left!=null&&temp_q.left==null)||(temp_p.left==null&&temp_q.left!=null)||(temp_p.right!=null&&temp_q.right==null)||(temp_p.right==null&&temp_q.right!=null)||temp_p.val!=temp_q.val||(temp_p.left!=null&&temp_q.left!=null&&temp_p.left.val!=temp_q.left.val)||(temp_p.right!=null&&temp_q.right!=null&&temp_p.right.val!=temp_q.right.val))return false; if(temp_p.left!=null)queue_p.offer(temp_p.left); if(temp_p.right!=null)queue_p.offer(temp_p.right); if(temp_q.left!=null)queue_q.offer(temp_q.left); if(temp_q.right!=null)queue_q.offer(temp_q.right); index_p--; } } if(queue_q.isEmpty()&&queue_p.isEmpty()){ return true; }else{ return false; } } }
时间复杂度:O(N)
空间复杂度:O(h) (广度则是最大的一层的节点个数。)
思路: 方法一、递归 方法二、迭代 + 队列
复杂度分析:
代码(C++):
方法一、递归法(Recursion):
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (!p && !q) return true;
if (!p || !q) return false;
return p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
方法二、迭代法:
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
queue<TreeNode*> p1, q1;
p1.push(p);
q1.push(q);
while (!p1.empty() && !q1.empty()) {
TreeNode* node_p = p1.front();
p1.pop();
TreeNode* node_q = q1.front();
q1.pop();
if (!node_p && !node_q) continue;
if (!node_p || !node_q || (node_p->val != node_q->val)) return false;
p1.push(node_p->left);
p1.push(node_p->right);
q1.push(node_q->left);
q1.push(node_q->right);
}
return true;
}
};
DFS
递归,分解子问题,把当前两棵树是否相同的问题分解为:
递归出口: 当树高度为 1 时(到叶节点时),判断递归出口
BFS
借助队列进行层序遍历, 判断每层的结构是否相同。每次取队头元素的时候比较两棵树的队头元素是否一致。如果不一致,直接返回 false。如果访问完都没有发现不一致就返回 true。
//DFS
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);
}
}
}
//BFS
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while (!queue.isEmpty()){
TreeNode first = queue.poll();
TreeNode second = queue.poll();
if (first == null && second == null) {
continue;
} else if (first == null || second == null) {
return false;
} else if (first.val != second.val) {
return false;
}
queue.offer(first.left);
queue.offer(second.left);
queue.offer(first.right);
queue.offer(second.right);
}
return true;
}
}
难度简单
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:
输入:p = [1,2], q = [1,null,2]
输出:false
示例 3:
输入:p = [1,2,1], q = [1,1,2]
输出:false
提示:
[0, 100]
内-104 <= Node.val <= 104
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
//base case
if(!(p||q)) return true;
if((p && !q)||(q && !p)) return false;
return (isSameTree(p->left,q->left)&&isSameTree(p->right,q->right)&&p->val == q->val)?true:false;
}
};
DFS 除了几个 corner case之外 直接递归比较
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
if p and not q:
return False
if not p and q:
return False
if p.val != q.val:
return False
else:
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
时间复杂度:O(n) n 为节点个数
空间复杂度:O(h) h 为树的深度
DFS
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
}
if (p.val != q.val) {
return false;
}
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
时间复杂度: O(N) 空间复杂度: O(h)
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null)
return true;
if (p == null || q == null)
return false;
return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null) return true;
else if(p == null || q == null) return false;
boolean cur = p.val == q.val;
boolean left = isSameTree(p.left, q.left);
boolean right = isSameTree(p.right, q.right);
return cur && left && right;
}
参考官方解
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);
}
}
}
递归
递归项: 比较2个树相等可以抽象为, 2个树根节点的值相等, 左右子树对应相等
递归退出条件: 对应节点的值不相等, 或者左右子树不相等
var isSameTree = function(p, q) {
if (p === null && q === null) {
return true
} else if (p!== null && q!== null) {
// 比较节点值是否相等
const isNodeSame = p.val === q.val
if (!isNodeSame) { return false }
const isLeftSame = isSameTree(p.left, q.left)
if (!isLeftSame) { return false }
const isRightSame = isSameTree(p.right, q.right)
if (!isRightSame) { return false }
return true
} else {
return false
}
};
m, n分别为2个树的节点数
class Solution: def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool: if not p and not q: return True elif not p or not q: return False elif p.val != q.val: return False else: return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
动态规划,自底向上,
最简子结构:从叶子节点的情况
逻辑关系:左右子树比较
实现方式:递归(迭代还想不到方法)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
//判断根节点的情况
if(p == nullptr && q == nullptr)return true;
if(p == nullptr || q == nullptr)return false;
//子节点的情况
if(p->val != q->val)return false;
//说明下面是值相等了,直接进行子树的比较
//比较左右子树的情况,递归
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
};
复杂度分析
树的遍历
# DFS
class Solution(object):
def isSameTree(self, p, q):
"""
:type p: TreeNode
:type q: TreeNode
:rtype: bool
"""
if not p and not q:
return True
if not p or not q or p.val != q.val:
return False
return self.isSameTree(p.right, q.right) and self.isSameTree(p.left, q.left)
class Solution(object): def isSameTree(self, p, q): """ :type p: TreeNode :type q: TreeNode :rtype: bool """ if not p and not q: return True elif not p or not q: return False que1 = [q] que2 = [p] while que1 and que2: node1 = que1.pop() node2 = que2.pop() if node1.val != node2.val: return False l1, r1 = node1.left, node1.right l2, r2 = node2.left, node2.right if (not l1) ^ (not l2) or (not r1) ^ (not r2): return False if l1: que1.append(l1) if r1: que1.append(r1) if l2: que2.append(l2) if r2: que2.append(r2) return not que1 and not que2
### 复杂度分析
+ 时间复杂度:O(min(m,n))
+ 空间复杂度:O(min(m,n))
递归,深度优先搜索
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;
}
return isSameTree(p.left,q.left)&& isSameTree(p.right,q.right);
}
}
时间复杂度O(N);
空间复杂度O(1);
class Solution(object): def isSameTree(self, p, q): """ :type p: TreeNode :type q: TreeNode :rtype: bool """ return self.check(p,q)
def check(self,p,q):
if(p==None and q==None):
return True
if(p!=None and q!=None):
if(p.val==q.val):
return self.check(p.left,q.left) and self.check(p.right,q.right)
else:
return False
else:
return False
class Solution(object): def isSameTree(self, p, q): """ :type p: TreeNode :type q: TreeNode :rtype: bool """ if not p and not q: return True elif not p or not q: return False elif p.val!=q.val: return False else: return self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
var isSameTree = function(p, q) {
if(p==null&&q==null) return true;
if(p==null||q==null) return false;
return p.val==q.val&&isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
};
LeetCode题目连接: 100. 相同的树 https://leetcode-cn.com/problems/same-tree/
DFS:深度优先搜索 BFS:广度优先搜索 【层序遍历】
(1) DFS:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
def dfs(node1, node2):
if not node1 and not node2:
return True
elif not node1 or not node2:
return False
if node1.val != node2.val:
return False
return dfs(node1.left, node2.left) and dfs(node1.right, node2.right)
return dfs(p, q)
复杂度分析
(2) BFS:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
deque = collections.deque([(p, q)])
while deque:
node1, node2 = deque.popleft()
if not node1 and not node2:
continue
elif not node1 or not node2:
return False
if node1.val != node2.val:
return False
deque.append((node1.left, node2.left))
deque.append((node1.right, node2.right))
return True
复杂度分析
1.前端可以直接判断两个数组是否相同 2.参考官解可以使用递归
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} p
* @param {TreeNode} q
* @return {boolean}
*/
var isSameTree = function(p, q) {
return JSON.stringify(p) === JSON.stringify(q)
};
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} p
* @param {TreeNode} q
* @return {boolean}
*/
var isSameTree = function(p, q) {
if(p === null && q === null) return true
if(p === null || q === null) return false // 不能一个为空一个不为空
if(p.val!==q.val){
return false;
}
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
};
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if not p and q:
return False
if p and not q:
return False
if not p and not q:
return True
else:
l = self.isSameTree(p.left, q.left)
r = self.isSameTree(p.right, q.right)
return l&r&(p.val==q.val)
dfs,判断两个节点,是否不同时为空,或节点的值不相同。 递归判断节点的左右两侧子节点。
/**
* @param {TreeNode} p
* @param {TreeNode} q
* @return {boolean}
*/
var isSameTree = function (p, q) {
if (p === null && q === null) {
return true;
}
if (p === null || q === null) {
return false;
}
if (p.val !== q.val) {
return false;
}
return isSameTree(p.left, q.left) && isSameTree(p.right , q.right);
};
复杂度分析不是很会,不一定对,如果有错,请指正。
class Solution(object):
def isSameTree(self, p, q):
"""
:type p: TreeNode
:type q: TreeNode
:rtype: bool
"""
if not p or not q:
return p == q
if p.val != q.val:
return False
outside = self.isSameTree(p.left, q.left)
inside = self.isSameTree(p.right, q.right)
isSame = outside and inside
return isSame
DFS
var isSameTree = function(p, q) {
if (!p && !q) return true
if (!p || !q) return false
if (p.val != q.val) return false
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right)
};
时间复杂度: O(N)
空间复杂度: O(1)
* 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 boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null)return true;
else if(p!=null&&q!=null&&p.val==q.val){
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
else return false;
}
}
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) return true; if (p == null || q == null) return false; if (p.val != q.val) { return false; } return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); } }
思路: 递归
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) return true; if (p == null || q == null) return false; if (p.val != q.val) return false; return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); } }
时间复杂度:O(N) 空间复杂度:O(h)
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
elif not p or not q:
return False
elif p.val != q.val:
return False
else:
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p ==nullptr && q ==nullptr)
{
return true; //对称
}
if(p ==nullptr || q ==nullptr)
{
return false;//不对称
}
if(q->val !=p->val)
{
return false;//内存不相等
}
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
};
递归
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if p == None and q==None:
return True
if p == None and q!=None:
return False
if q == None and p!=None:
return False
if p.val == q.val:
return self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
return False
复杂度分析
DFS+对某一节点需要进行的操作。那么主要就是弄清对某一节点需要进行哪些判断。怎么样的树可以称为是相同的树?
相同的树:结构相同,对应位置相同节点的值也相同。
根据以上定义,就可以分析对当前遍历到的两个节点需要进行的操作了。
1、两节点是否为空,若同时为空,则必定为相同的树(因为压根没有);
2、若两节点不同时为空,且也不同时非空,则必不为相同的树(一个有一个没有);
3、若两节点都非空,但值不同,仍然不是相同的树;
4、若均不满足上述情况,说明到当前两节点为止的树为相同的树,继续往左右DFS;
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p&&!q){
return true; //两棵树均为空则必相同
}
else if(!p||!q){
return false; //有一棵树为空
}
else if(p->val!=q->val){
return false; //根节点不相等
}
else{
//深度优先遍历
return isSameTree(p->left, q->left)&&isSameTree(p->right, q->right);
}
}
};
复杂度分析
时间复杂度:O(n)
空间复杂度:O(h) h为两树相同部分的深度
解题思路:
先判断 p是否为空。 Y:在判断q是否为空。
N:一样判断q是否为空
在对比两者的值是否相同,Y:递归再次调用左右两个节点。
最终返回就是结果
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(nullptr == p){
if( nullptr == q){
return true;
}else{
return false;
}
}else{
if(nullptr == q){
return false;
}
}
if(p->val == q->val){
return isSameTree(p->left , q->left) && isSameTree(p->right , q->right) ;
}else{
return false;
}
}
};
递归 var isSameTree = function(p, q) { if(p === null && q === null) return true; else if(p === null || q === null) return false; else { let cur = p.val === q.val ? true : false; let left = isSameTree(p.left,q.left); let right = isSameTree(p.right,q.right); return cur && left && right; } };
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
if not p or not q:
return False
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if(p == null && q == null) return true; if(p == null || q == null) return false; if(p.val != q.val) return false; return isSameTree(p.left,q.left) && isSameTree(p.right,q.right); } }
思路 相同的定义:树的形状一样,每个节点值也一样 因此按照相同的顺序,遍历两个树,比较对应位置的值,如果不一样,返回 false,如果都一样,返回 true。
代码 function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean { // 特判 if (!p && !q) return true if (!p || !q || p.val !== q.val) return false // 递归对比每个节点 return isSameTree(p.left, q.left) && isSameTree(p.right, q.right) }; 分析 时间复杂度:O(min(p,q)) 空间复杂的:O(min(p,q))
解法一: 递归法
先比较两颗树的节点上的值是否相等,然后递归比较前一颗树的左子树与后一颗树的左子树是否相同,再然后递归比较前一颗树的右子树与后一颗树的右子树是否相同;
递归的终止条件:
当获取某个树(或者两个树)的节点都为空的时候,就返回结果
解法二:层序遍历
层序遍历会遍历每一层的数据,在遍历每一层的时候就直接比较就行。
我采用四个队列的形式,两个正式队列,两个临时队列,两个正式队列分别存储两个树的节点,两个临时队列存储分别存储每次遍寻的两个子树的每一层
解法一:
<?php
/**
* Definition for a binary tree node.
* class TreeNode {
* public $val = null;
* public $left = null;
* public $right = null;
* function __construct($val = 0, $left = null, $right = null) {
* $this->val = $val;
* $this->left = $left;
* $this->right = $right;
* }
* }
*/
class Solution
{
/**
* @param TreeNode $p
* @param TreeNode $q
* @return Boolean
*/
function isSameTree($p, $q)
{
if (!$p || !$q) {
return !$p && !$q;
}
return $p->val === $q->val &&
$this->isSameTree($p->left, $q->left) &&
$this->isSameTree($p->right, $q->right);
}
}
解法二:
<?php
/**
* Definition for a binary tree node.
* class TreeNode {
* public $val = null;
* public $left = null;
* public $right = null;
* function __construct($val = 0, $left = null, $right = null) {
* $this->val = $val;
* $this->left = $left;
* $this->right = $right;
* }
* }
*/
class Solution
{
/**
* @param TreeNode $p
* @param TreeNode $q
* @return Boolean
*/
function isSameTree($p, $q)
{
$currentQueueA = [$p];
$currentQueueB = [$q];
while ($currentQueueA && $currentQueueB) {
$nextQueueA = [];
$nextQueueB = [];
$isOk = $this->isSameCurrentNode($currentQueueA, $currentQueueB, $nextQueueA, $nextQueueB);
if (!$isOk) {
return false;
}
$currentQueueA = $nextQueueA;
$currentQueueB = $nextQueueB;
}
return true;
}
/**
* 判断当前节点是否相等
*
* @param $currentQueueA
* @param $currentQueueB
* @param $nextQueueA
* @param $nextQueueB
* @return bool|false
* @author 陈维锐
* @date 2021/12/25
*/
private function isSameCurrentNode($currentQueueA, $currentQueueB, &$nextQueueA, &$nextQueueB)
{
if (count($currentQueueA) !== count($currentQueueB)) {
return false;
}
for($i = 0; $i < count($currentQueueA); $i++) {
if (!$this->isSameNodeVal($currentQueueA[$i], $currentQueueB[$i])) {
return false;
}
// 这里不能用 $currentQueueA[$i]->left 来加入数组。
// 因为,如果$currentQueueA[$i]->left 有值 ,$currentQueueA[$i]->right 无值
// currentQueueB[$i]->left 无值 ,$currentQueueB[$i]->right 有值
// 这样会导致 $currentQueueA[$i]->left 和 $currentQueueB[$i]->right 在比较值
$currentQueueA[$i] && array_push($nextQueueA, $currentQueueA[$i]->left);
$currentQueueB[$i] && array_push($nextQueueB, $currentQueueB[$i]->left);
$currentQueueA[$i] && array_push($nextQueueA, $currentQueueA[$i]->right);
$currentQueueB[$i] && array_push($nextQueueB, $currentQueueB[$i]->right);
}
return true;
}
/**
* 判断当前节点的值是否相等
*
* @param $nodeAVal
* @param $nodeBVal
* @return bool
* @author 陈维锐
* @date 2021/12/25
*/
private function isSameNodeVal($nodeA, $nodeB)
{
// 这里杜绝了A节点与B节点有一个节点为null的问题(两个都为null就直接返回true)
if (!$nodeA || !$nodeB) {
return $nodeA === $nodeB;
}
return $nodeA->val === $nodeB->val;
}
}
令n为链表总的节点数
思路:
树相同->即根节点相同+左子树相同+右子树相同;
步骤:
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null){
return true;
}else if(p!=null&&q!=null){
if(p.val != q.val){
return false;
}
if(isSameTree(p.left,q.left) && isSameTree(p.right,q.right)){
return true;
}else{
return false;
}
}else{
return false;
}
}
}
时间:O(min(m,n)),m,n分别为树的结点数;
空间:O(min(m,n)),最坏情况树的高度等于结点数;
100. 相同的树
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/same-tree/
前置知识
题目描述
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1 / \ / \ 2 3 2 3
输出: true 示例 2:
输入: 1 1 / \ 2 2
输出: false 示例 3:
输入: 1 1 / \ / \ 2 1 1 2
输出: false