代码随想录DAY15|102. 层序遍历 226.翻转二叉树 101.对称二叉树

102. 层序遍历

题目链接: https://leetcode.com/problems/binary-tree-level-order-traversal/

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
       List<List<Integer>> result = new ArrayList<>();
       if (root == null) {
           return result;
       }
       Deque<TreeNode> queue = new LinkedList<>();
       queue.offer(root);
       while (!queue.isEmpty()) {
           List<Integer> itemlist = new ArrayList<>();
           int size = queue.size();
           // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
           while (size -- > 0) {
               TreeNode curr = queue.poll();
               itemlist.add(curr.val);
               if (curr.left != null) {
                   queue.offer(curr.left);
               }
               if (curr.right != null) {
                   queue.offer(curr.right);
               }
           }
           result.add(itemlist);
       }
       return result;
    }
}

思路:
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
在这里插入图片描述

226. 翻转二叉树

题目链接:https://leetcode.com/problems/invert-binary-tree/
在这里插入图片描述
方法1: 递归法 前序遍历 dfs 深度优先

class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 递归法 前序遍历
        if (root == null) {
            return root;
        }
        swap(root); //中
        invertTree(root.left); //左
        invertTree(root.right); //右
        return root;
    }
    public void swap(TreeNode node) {
        TreeNode temp = node.left;
        node.left = node.right;
        node.right = temp;
    }
}

方法二:迭代法 前序 中左右 中右左都可以 dfs 深度优先

class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 迭代法 dfs
        Deque<TreeNode> stack = new LinkedList<>();
        if (root == null) return root; // 优先处理空
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode curr = stack.pop(); // 中
            swap(curr);
            if (curr.right != null) stack.push(curr.right); //不放入空节点
            if (curr.left != null) stack.push(curr.left);
        }
        return root;
    }
    public void swap(TreeNode node) {
        TreeNode temp = node.left;
        node.left = node.right;
        node.right = temp;
    }
}

方法三:层序遍历 bfs 广度优先

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {return null;}
        ArrayDeque<TreeNode> deque = new ArrayDeque<>();
        deque.offer(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            while (size-- > 0) {
                TreeNode node = deque.poll();
                swap(node);
                if (node.left != null) deque.offer(node.left);
                if (node.right != null) deque.offer(node.right);
            }
        }
        return root;
    }

    public void swap(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

思路:

  1. 把每一个节点的左右孩子翻转一下
  2. 前序遍历,后序遍历,层序遍历都可以,中序翻转两遍不行
  3. 中序
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        invertTree(root->left);         // 左
        swap(root->left, root->right);  // 中
        invertTree(root->left);         // 注意 这里依然要遍历左孩子,因为中间节点已经翻转了
        return root;
    }
};

101.对称二叉树

题目链接:https://leetcode.com/problems/symmetric-tree

Input: root = [1,2,2,3,4,4,3]
Output: true
Input: root = [1,2,2,null,3,null,3]
Output: false

在这里插入图片描述

递归三部曲:

  1. 确定递归函数的参数和返回值:用来比较根结点的两个子树是否相互翻转,进而判定对称,所以参数为左右子树节点,返回bool
  2. 确定终止条件:比较节点数值是否相等,首要是为空的情况,三种节点为空的情况,最后剩下的是节点不为空且数值相同。
  3. 确定单层递归的逻辑:此时左右节点都不为空,且数值相同。比较二叉树外侧内侧是否对称,都对称返回true

方法一:递归法,后序遍历,比较内外侧

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);
    }
    public boolean compare(TreeNode left, TreeNode right) {
        if (left == null && right == null) {
            return true;
        } else if (left == null && right !=null) {
            return false;
        } else if (left != null && right == null) {
            return false;
        } else if (left.val != right.val) {
            return false;
        } else {
            return compare(left.left,right.right) && compare(left.right, right.left); // 左,右,中(逻辑处理),后序遍历
        }
    }
}

方法二:迭代法,队列or栈

class Solution {
    public boolean isSymmetric(TreeNode root) {
        // queue
        Deque<TreeNode> queue = new LinkedList<>();
        // root != null
        queue.offer(root.left);
        queue.offer(root.right);
        while (!queue.isEmpty()) {
            TreeNode leftNode = queue.poll();
            TreeNode rightNode = queue.poll();
            if (leftNode == null && rightNode == null) { 
                // here, if left == right == null, still exist other element in queue not compared, may be false, so should not return true
                continue;
            } else if (leftNode != null && rightNode == null) {
                return false;
            } else if (leftNode == null && rightNode != null) {
                return false;
            } else if (leftNode.val != rightNode.val) {
                return false;
            }
            queue.offer(leftNode.left);
            queue.offer(rightNode.right);
            queue.offer(leftNode.right);
            queue.offer(rightNode.left);
        }
        return true;
    }
}

思路:

  1. 同时遍历两棵树,“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。
  2. 正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值