层序遍历
/**
* 二叉树的层序遍历
*/
class QueueTraverse {
/**
* 存放一层一层的数据
*/
public List<List<Integer>> resList = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
traverse(root, resList);
return resList;
}
/**
* 树的孩子节点可能有不止两个
*/
public void traverse(TreeNode node, List<List<Integer>> resList) {
// 判空
if (node == null) {
return;
}
// 准备
ArrayDeque<TreeNode> que = new ArrayDeque<>();
TreeNode cur;
// 循环开始
que.offer(node);
while (!que.isEmpty()) {
//len获取到的是每层一开始的数据大小
int len = que.size();
//对每一层的分别建立一个list存放本层数据
List<Integer> subList = new ArrayList(len);
while (len > 0) {
//取出本层节点并删除
cur = que.poll();
len--;
// visit
subList.add(cur.val);
if (cur.left != null) {
que.offer(cur.left);
}
if (cur.right != null) {
que.offer(cur.right);
}
}
//一层的数据遍历添加完毕 开始下一层
resList.add(subList);
}
}
/**
* 单纯遍历所有元素
*/
public void visit(TreeNode root) {
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
TreeNode p = root,temp = null;
queue.offer(p);
while (!queue.isEmpty()) {
// visit 节点
temp = queue.poll();
System.out.println(temp.val);
if (p.left != null) {
queue.offer(temp.left);
}
if (p.right != null) {
queue.offer(temp.right);
}
}
}
}
LeetCode 226.翻转二叉树
分析1.0
仔细看题,题目中的翻转二叉树是整个树一起翻转,不是只翻转节点的左右孩子
选择遍历顺序-中序遍历(左子树翻转(左子树成了右子树),根树翻转,右子树翻转)左子树翻转了两次
class Solution {
public TreeNode invertTree(TreeNode root) {
preOrder(root);
return root;
}
public void preOrder(TreeNode root){
if(root == null){
return;
}
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
preOrder(root.left);
preOrder(root.right);
return;
}
}
LeetCode 101.对称二叉树 2
失误 对称二叉树比较的是子树,不光是子节点
比较每个节点的左右子树是否相等,树又是由节点组成的,就是同步遍历根节点左右两颗子树,比较节点是否相等
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null){
return false;
}
return visit(root.left, root.right);
}
public boolean visit(TreeNode node1, TreeNode node2){
if(node1 == null && node2 != null){
return false;
}
if(node2 == null && node1 != null){
return false;
}
if(node1 == null && node2 == null){
return true;
}
if(node1.val != node2.val){
return false;
}
visit(node1.left, node2.left);
visit(node1.right, node2.right);
return true;
}
}
分析2.0
遍历子树并不是按照一样的逻辑顺序,左子树的左子树要和右子树的右子树相等 以此类推class Solution {
/**
* 递归法
*/
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
private boolean compare(TreeNode left, TreeNode right) {
if (left == null && right != null) {
return false;
}
if (left != null && right == null) {
return false;
}
if (left == null && right == null) {
return true;
}
if (left.val != right.val) {
return false;
}
// 比较外侧
boolean compareOutside = compare(left.left, right.right);
// 比较内侧
boolean compareInside = compare(left.right, right.left);
return compareOutside && compareInside;
}
}
总结
- 树类题目注意区别孩子节点和子树
- 数组、字符串移除某个元素后,长度会发生变化,遍历中注意索引发生变化,树在遍历过程中的操作也会影响原本的遍历思路
- 不同的深度遍历顺序有不同的使用场景,注意具体问题具体分析
- 节点要非null才能进行操作 类似栈、队列非空才能操作一样
常用变量名增量更新
size、val、ans、cnt、cur、pre、next、left、right、index、gap、tar、res、src、len、start、end、flag、ch
标签:right,return,层序,随想录,二叉树,TreeNode,null,root,left From: https://www.cnblogs.com/cupxu/p/17071677.html