LeetCode每日一题: 单值二叉树(No.965)

题目:单值二叉树


如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。
只有给定的树是单值二叉树时,才返回 true;否则返回 false。
复制代码

示例:


输入:[1,1,1,1,1,null,1]
输出:true
复制代码

输入:[2,2,2,5,2]
输出:false
复制代码

思考:


这道题只要遍历二叉树的每个节点然后比较每个节点的值即可。所以这题其实就是回顾二叉树的遍历方法。
复制代码

实现:


/**
 * Definition for a binary tree node.
 * public class TreeNode {
*     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
  class Solution {
    public ArrayList<Integer> list = new ArrayList<>();
    public boolean isUnivalTree(TreeNode root) {
        //遍历二叉树将节点值加入到list中
        dfs(root);
        //比较节点值是否相等
        for (int count = 1; count < list.size(); count++) {
            if (list.get(0) != list.get(count)) {
                return false;
            }
        }
        return true;
    }
    //递归遍历二叉树
    private void dfs(TreeNode node) {
        if (node != null) {
            list.add(node.val);
            dfs(node.left);
            dfs(node.right);
        }
    }
}
复制代码

二叉树遍历方法:


深度遍历:

1.先序遍历
遍历顺序:根节点-左子节点-右子节点
递归实现:

 private void dfs(TreeNode node) {
        if (node != null) {
            //将根节点放入list
            list.add(node.val);
            //递归左节点
            dfs(node.left);
            //递归右节点
            dfs(node.right);
        }
    }
复制代码

非递归实现:

   public void dfs(TreeNode root) {
    //非递归需要用栈来记录节点情况
    Stack<TreeNode> stack = new Stack<TreeNode>();
    //记录当前节点
    TreeNode cur = root;
    //当前节点不为空且栈不为空时循环
    while (cur != null || !stack.isEmpty()) {
        //当前节点不为空,一直循环,该循环会一直遍历根节点的左子节点,左子节点的左子节点...直至最左叶子节点。
        while (cur != null) {
             //将该节点值放入list
            list.add(cur.val);
            //将当前节点入栈
            stack.push(cur);
            //当前节点指向其左节点
            cur = cur.left;
     } 
        //遍历到最左叶子节点跳出循环
        //栈不为空时,取出栈顶节点,即最左叶子节点,将当前节点指向其右子节点。
        //之后回到外层循环,再遍历右子节点的左子节点
       if (!stack.isEmpty()) {
            //取出栈顶元素
           TreeNode node = stack.pop();
           //当前节点指向栈顶节点的右子节点
           cur = node.right;
       }
  }
复制代码

2.中序遍历
遍历顺序:左子节点-根节点-右子节点
递归实现:

 private void dfs(TreeNode node) {
        if (node != null) {
            //递归左节点
            dfs(node.left);
            //将根节点放入list
            list.add(node.val);
            //递归右节点
            dfs(node.right);
        }
    }
复制代码

非递归实现:

  public void dfs(TreeNode root) {
        //非递归需要用栈来记录节点情况
        Stack<TreeNode> stack = new Stack<TreeNode>();
        //记录当前节点
        TreeNode cur = root;
        //当前节点不为空且栈不为空时循环
        while (cur != null || !stack.isEmpty()) {
        //当前节点不为空,一直循环,该循环会一直遍历根节点的左子节点,左子节点的左子节点...直至最左叶子节点。
            while (cur != null) {
                //将当前节点入栈
                stack.push(cur);
                //当前节点指向其左节点
                cur = cur.left;
            }
             //遍历到最左叶子节点跳出循环
            //栈不为空时,取出栈顶节点,即最左叶子节点,将该节点放入list,再将当前节点指向该节点的右子节点
            //之后回到外层循环,再遍历右子节点的左子节点
            if (!stack.isEmpty()) {
                //取出栈顶节点
                TreeNode node = stack.pop();
                //将该节点放入list
                list.add(node.val);
                //将当前节点指向该节点的右子节点
                cur = node.right;
            }
        }
    }
复制代码

3.后序遍历
遍历顺序:左子节点-根节点-右子节点
递归实现:

 private void dfs(TreeNode node) {
        if (node != null) {
            //递归左节点
            dfs(node.left);
            //递归右节点
            dfs(node.right);
             //将根节点放入list
            list.add(node.val);
        }
    }
复制代码

非递归实现:

public void dfs(TreeNode root) {
        //非递归需要用栈来记录节点情况
        Stack<TreeNode> stack = new Stack<TreeNode>();
        //记录当前节点
        TreeNode cur = root;
        //后续遍历需要一个记录当前节点右子节点是否已被访问的标记,当cur.right=flag时说明该节点右子节点已被访问过
        TreeNode flag = null;
        //当前节点不为空时一直循环,该循环会一直遍历根节点的左子节点,左子节点的左子节点...直至最左叶子节点。
        while (cur != null) {
            //将当前节点入栈
            stack.push(cur);
            //当前节点指向其左节点
            cur = cur.left;
        }
        //遍历到最左叶子节点跳出循环
        //栈不为空时循环取出栈顶节点,即最左叶子节点
        while (!stack.isEmpty()) {
            //取出栈顶节点,将当前节点指向栈顶节点
            cur = stack.pop();
            //如果当前节点的右子节点为空或者右子节点被访问过
            if (cur.right == null || cur.right == flag) {
               //将当前节点放入list
                list.add(cur.val);
                //记录当前节点
                flag = cur;
            } else {
                //当前节点不为空且没被访问过,则将当前节点入栈
                stack.push(cur);
                //将当前接单指向其右子节点
                cur = cur.right;
                //右子节点不为空
                while (cur != null) {
                    //将右子节点入栈
                    stack.push(cur);
                    //再将当前节点指向其左子节点
                    cur = cur.left;
                }
            }
        }
    }
复制代码
层次遍历:

遍历顺序:按从顶层到底层的次序访问树中元素,在同一层中,从左到右进行访问。
实现:

  public void bfs(TreeNode root) {
        //层次遍历需要用队列来记录节点情况
        ArrayDeque<TreeNode> queue = new ArrayDeque<TreeNode>();
        //记录当前节点
        TreeNode cur = root;
        //将根节点加入队列
        queue.add(root);
        //队列不为空循环队列
        while (!queue.isEmpty() ) {
           //取出队列中首个节点
            TreeNode node = queue.remove();
            //将该节点放入list
            list.add(node.val);
            //左子节点不为空将左子节点入队                
            if (node.left != null) {
                queue.add(node.left);
            }
            //右子节点不为空将右子节点入队
            if (node.right != null) {
                queue.add(node.right);
            }
        }
    }复制代码

转载于:https://juejin.im/post/5cb416aa6fb9a068547349c3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值