🎇个人主页: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;}
}