个人主页:Ice_Sugar_7
所属专栏:数据结构刷题
欢迎点赞收藏加关注哦!
题目链接
思路:现在有两个节点root1、root2,它们有共同的根节点,如果root1的左子树、右子树分别和root2的右子树、左子树相同,那就是对称的
需要注意的是,题干给的方法只有一个参数root,但是我们要两边同时走,也就需要两个参数,所以需要额外写一个方法
public boolean isSymmetric(TreeNode root) {
if(root == null) {
return true;
}
return Symmetric(root.left,root.right);
}
public boolean Symmetric(TreeNode root1,TreeNode root2) {
//整体思路是前序遍历,先对根节点进行判断
if(root1 == null && root2 == null) {
return true;
}
//到这里,root1和root2至少有一个不为空,接下来判断有没有一个是空的,若有,那就不是对称的了
if(root1 == null || root2 == null) {
return false;
}
//到这里,root1和root2都不为空
//比较根节点的值
if(root1.val != root2.val) {
return false;
} else {
//从else开始就是遍历根节点的左子树和右子树
boolean ret1 = Symmetric(root1.left,root2.right);
boolean ret2 = Symmetric(root1.right,root2.left);
if(ret1 && ret2) {
return true;
} else {
return false;
}
}
}
题目链接
思路:用队列存储二叉树每一层的元素,定义一个变量size记录入队后队列的元素个数,也就是二叉树每一层的元素个数
为什么要记录呢?因为我们需要弹出这一层的节点,然后“带”出下一层的节点的,要知道弹出多少个节点
class Solution {
Queue<TreeNode> queue = new LinkedList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
if(root == null)
return new ArrayList<>();
List<List<Integer>> ret = new ArrayList<>();
queue.offer(root);
while(!queue.isEmpty()) {
List<Integer> list = new ArrayList<>();
int size = queue.size();
//这个循环实现:将第k层的元素出队列,让第k+1层元素入队
while(size-- > 0) {
TreeNode top = queue.poll(); //取当前队头的元素
list.add(top.val); //每取出一个,就放到list里面
if(top.left != null)
queue.offer(top.left);
if(top.right != null)
queue.offer(top.right);
}
ret.add(list); //将list放进ret,相当于将一维数组放进二维数组
}
return ret;
}
}
题目链接
思路:根据前序遍历推出根节点,然后找出根节点在中序遍历数组中的位置,这样就能知道剩下的节点是在左子树还是右子树
以上图为例,由中序遍历的数组可知,20在以3为根节点的右子树,而在preorder中,20是右子树部分第一个数,说明它是这个右子树的根节点
(这里解释一下原因:因为前序遍历是按照根、左、右的顺序遍历的,所以遇到的第一个节点就是根节点)
以3为根节点分割好之后,继续对左右子树进行分割:先找出子树根节点在中序数组的位置,然后分割为更小的区间
class Solution {
public int prei; //记录遍历到前序数组的哪个下标
public TreeNode buildTree(int[] preorder, int[] inorder) {
return devide(preorder,inorder,0,inorder.length - 1);
}
//val:要找的根节点的值
public int findIndex(int val,int[] inorder) {
for(int i = 0;i < inorder.length;i++) {
if(inorder[i] == val) {
return i; //返回它在inorder中的下标
}
}
return -1;
}
//begin、end:子树的起始、终止下标
public TreeNode devide(int[] preorder,int[] inorder,int begin,int end) {
//当end < begin时递归结束,注意end == begin时也要进行递归,此时也要创建节点
if(end < begin)
return null;
//从中序遍历数组中找到“分割点”
int dev = findIndex(preorder[prei++],inorder); //dev:分割点在inorder中的下标
//分割点就是根节点
TreeNode node = new TreeNode(inorder[dev]);
//通过递归连接左右子树
node.left = devide(preorder,inorder,begin,dev-1);
node.right = devide(preorder,inorder,dev+1,end);
return node;
}
}