day17-102/104/101/226/112-树

94 阅读2分钟

第一题

题目

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)

image.png

思路

1、二叉树的广度优先遍历(官方题解,我第一次接触,根本想不出来哎)

返回值为List<List<Integer>>(让我无缘无故想起了数组的一种题,杨辉三角,确实关于list的add写法差不多)

官方题解借助了队列进行解答

  • 首先根元素入队

  • 队列不为空的时候

    1、求队列的size进行遍历

    2、依次从队列中取出元素进行操作,再进行下次迭代

2、还看到有人写了递归的写法,感觉666,果然不是我的脑子想出来的

代码

1、广度+队列

import java.util.*;
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(root == null) {
            return res;
        };
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            List<Integer> row = new ArrayList<Integer>();
            int len = queue.size();
            for(int i = 0; i < len; i++) {
                TreeNode newRoot = queue.poll();
                row.add(newRoot.val);
                if(newRoot.left != null) {
                    queue.offer(newRoot.left);
                };
                if(newRoot.right != null) {
                    queue.offer(newRoot.right);
                };
            };
            res.add(row);
        };
        return res;

    }
}

2、递归

class Solution {
    List<List<Integer>> list = new ArrayList<>();
    public List<List<Integer>> levelOrder(TreeNode root) {
        dns(root,0);
        return list;
    }
    public void dns(TreeNode node,int lever){
        if(node == null) return;
        if(list.size()==lever) list.add(new ArrayList<Integer>());

        list.get(lever).add(node.val);

        dns(node.left,lever+1);
        dns(node.right,lever+1);
    }
}

第二题

题目

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点

image.png

思路

1、根据第一题的思路,我是不是也可以从第一题获取,广度优先遍历,直接从第一题代码贴下来修改,deep++

2、深度优先遍历,取max

代码

1、广度优先遍历

class Solution {
    public int maxDepth(TreeNode root) {
        int deep = 0;
        if(root == null) {
            return deep;
        };
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int len = queue.size();
            for(int i = 0; i < len; i++) {
                TreeNode newRoot = queue.poll();
                if(newRoot.left != null) {
                    queue.offer(newRoot.left);
                };
                if(newRoot.right != null) {
                    queue.offer(newRoot.right);
                };
            };
            deep++;
        };
        return deep;
    }
}

2、深度优先

import java.util.*;
class Solution {
    public int maxDepth(TreeNode root) {
        int deep = 0;
        if(root == null) {
            return deep;
        }
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        return Math.max(left, right) + 1;
    }
}

第三题

题目

给你一个二叉树的根节点 root , 检查它是否轴对称

image.png

思路

1、借助两个List,一个存储root的左子树节点,节点按照根-左-右,一个存储root的右子树节点,节点按照根-右-左,最后判断两个list是否相等

2、官方题解,双指针

代码

1、借助List

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root.right == null && root.left == null) return true;
        List<Integer> list1 = new ArrayList<Integer>();
        List<Integer> list2 = new ArrayList<Integer>();
        leftBianli(root.left, list1);
        rightBianli(root.right, list2);
        return list1.equals(list2);
    }
    public static void leftBianli(TreeNode root, List list) {
        if(root == null) {
            list.add(200);
            return;
        };
        list.add(root.val);
        leftBianli(root.left, list);
        leftBianli(root.right, list);
    }
    public static void rightBianli(TreeNode root, List list) {
        if(root == null) {
            list.add(200);
            return;
        };
        list.add(root.val);
        rightBianli(root.right, list);
        rightBianli(root.left, list);
    }
}

2、双指针

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return check(root, root);
    }
    public static boolean check(TreeNode left, TreeNode right) {
        if(left == null && right == null) {
            return true;
        }
        if(left == null || right == null) {
            return false;
        }

        return left.val == right.val && check(left.left, right.right) && check(left.right, right.left);
    }
}

第四题

题目

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点

image.png

思路

递归进行反转

代码

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null) return root;
        TreeNode left = root.left;
        TreeNode right = root.right;
        root.left = right;
        root.right = left;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}

第五题

题目

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

image.png

思路

1、使用递归

代码

1、递归

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null) {
            return false;
        }
        if(root.left == null && root.right == null) {
            return root.val == targetSum;
        };
        return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
    }
}