算法修炼Day15|● 层序遍历 102 ● 226.翻转二叉树 ● 101.对称二叉树

58 阅读3分钟
题目:102. 二叉树的层序遍历 - 力扣(LeetCode)
思路/想法:

预期结果是一个二维数组的形式,每层树节点就是一个子集。

使用队列实现,将每层节点加入队列中,并使用计数器循环记录每层节点的数量,将当前层作为一个子集进行输出。

代码实现:
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        if (root == null) return ans;
        que.offer(root);
        while (!que.isEmpty()) {
            List<Integer> list = new ArrayList<>();
            int size = que.size();
            while (size > 0) { // 循环输出一层树的节点值
                TreeNode temp = que.poll();
                list.add(temp.val);
                if (temp.left != null) que.offer(temp.left);
                if (temp.right != null) que.offer(temp.right);
                size--;
            }
            ans.add(list);
        }
        return ans;
    }
}
题目:107. 二叉树的层序遍历 II - 力扣(LeetCode)
思路/想法:

在上一题的基础上将获取到的结果进行反转。

代码实现:
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        if (root == null) return ans;
        que.add(root);
        while (!que.isEmpty()) {
            int size = que.size();
            List<Integer> list = new ArrayList<>();
            while (size > 0) {
                TreeNode temp = que.poll();
                list.add(temp.val);
                if (temp.left != null) que.add(temp.left);
                if (temp.right != null) que.add(temp.right);
                size--;
            }
            ans.add(list);
        }
        List<List<Integer>> res = new ArrayList<>();
        for (int i = ans.size() - 1; i >= 0; i--) {
            res.add(ans.get(i));
        }
        return res;
    }
}
题目:199. 二叉树的右视图 - 力扣(LeetCode)
思路/想法:

在上一题的基础上,只存储最后一个元素即可。

代码实现:
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        if (root == null) return ans;
        que.add(root);
        while (!que.isEmpty()) {
            int size = que.size();
            while (size > 0) {
                TreeNode temp = que.poll();
                if (temp.left != null) que.add(temp.left);
                if (temp.right != null) que.add(temp.right);
                if (size == 1) {
                    ans.add(temp.val);
                }
                size--;
            }
        }
        return ans;
    }
}
题目:637. 二叉树的层平均值 - 力扣(LeetCode)
思路/想法:

求没一层的和,取其均值加入结果集。

代码实现:
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> ans = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        if (root == null) return ans;
        que.add(root);
        while (!que.isEmpty()) {
            int size = que.size();
            List<Integer> list = new ArrayList<>();
            double levelSum = 0.00000;
            for (int i = 0; i < size; i++) {
                TreeNode temp = que.poll();
                levelSum += temp.val;
                if (temp.left != null) que.add(temp.left);
                if (temp.right != null) que.add(temp.right);

            }
            ans.add(levelSum / size);
        }
        return ans;
    }
}
题目:429. N 叉树的层序遍历 - 力扣(LeetCode)
思路/想法:

同样的思路和模板,在此基础上对潜在多个子节点进行判断加入队列。

代码实现:
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> ans = new ArrayList<>();
        Queue<Node> que = new LinkedList<>();
        if (root == null) return ans;
        que.add(root);
        while (!que.isEmpty()) {
            int size = que.size();
            List<Integer> list = new ArrayList<>();

            for (int i = 0; i < size; i++) {
                Node temp = que.poll();
                list.add(temp.val);
                List<Node> children = temp.children;
                if (children == null || children.size() == 0) {
                    continue;
                }
                for (Node child : children) {
                    if (child != null) {
                        que.add(child);
                    }
                }
            }
            ans.add(list);
        }
        return ans;
    }
}
题目:515. 在每个树行中找最大值 - 力扣(LeetCode)
思路/想法:

需要记录每一层的最大值,加入到结果集即可。

代码实现:
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        if (root == null) return ans;
        que.add(root);
        while (!que.isEmpty()) {
            int size = que.size();
            int maxValue = Integer.MIN_VALUE;
            while (size > 0) {
                TreeNode temp = que.poll();
                maxValue = Math.max(temp.val, maxValue);
                if (temp.left != null) que.add(temp.left);
                if (temp.right != null) que.add(temp.right);
                size--;
            }
            ans.add(maxValue);
        }
        return ans;
    }
}
题目:116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)
思路/想法:

抄了一遍,细节还没想明白

代码实现:
class Solution {
    public Node connect(Node root) {
        Queue<Node> que = new LinkedList<>();
        if (root == null) return null;
        que.add(root);
        while (!que.isEmpty()) {
            int size = que.size();
            Node temp = que.poll();
            if (temp.left != null) que.add(temp.left);
            if (temp.right != null) que.add(temp.right);
            for (int i = 1; i < size; i++) {
                Node next = que.poll();
                if (next.left != null) que.add(next.left);
                if (next.right != null) que.add(next.right);
                temp.next = next;
                temp = next;
            }
        }
        return root;
    }
}
题目:226. 翻转二叉树 - 力扣(LeetCode)
思路/想法:

递归调用方法,交换左右子树。

代码实现:
// 递归法DFS
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        swapNode(root);
        return root;
    }
    private void swapNode(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}
// 迭代法(BFS)
class Solution {
    public TreeNode invertTree(TreeNode root) {
        Queue<TreeNode> que = new LinkedList<>();
        if (root == null) return null;
        que.add(root);
        while (!que.isEmpty()) {
            int size = que.size();
            while (size > 0) {
                TreeNode temp = que.poll();
                swapNode(temp);
                if (temp.left != null) que.add(temp.left);
                if (temp.right != null) que.add(temp.right);
                size--;
            }
        }
        return root;
    }
    private void swapNode(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}
题目:101. 对称二叉树 - 力扣(LeetCode)
思路/想法:

递归法:分别比较左右子树的左右孩子和左右子树的右左孩子

代码实现:
// DFS
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);
    }
    boolean compare(TreeNode left, TreeNode right) {
        if (left == null && right != null) {
            return false;
        } else if (left != null && right == null) {
            return false;
        } else if (left == null && right == null) {
            return true;
        } else if (left.val != right.val) {
            return false;
        }

        boolean out = compare(left.left, right.right);
        boolean in = compare(left.right, right.left);
        return out && in;
    }
}
// 迭代BFS
class Solution {
    public boolean isSymmetric(TreeNode root) {
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root.left);
        que.add(root.right);
        while (!que.isEmpty()) {
            TreeNode tempLeft = que.poll();
            TreeNode tempRight = que.poll();
            if (tempLeft == null && tempRight == null) {
                continue;
            }
            if (tempLeft == null || tempRight == null || tempLeft.val != tempRight.val) {
                return false;
            }
            que.add(tempLeft.left);
            que.add(tempRight.right);
            que.add(tempLeft.right);
            que.add(tempRight.left);
        }
        return true;

    }
}