LeetCode.965-单一二叉树(Univalued Binary Tree)

这是悦乐书的第366次更新,第394篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第228题(顺位题号是965)。如果树中的每个节点具有相同的值,则二叉树是单一的。当且仅当给定树是单一时才返回true

    1
   / \   
  1   1
 / \   \
1   1   1

输入: [1,1,1,1,1,null,1]
输出: true

    2
   / \   
  2   2
 / \   
5   2   

输入: [2,2,2,5,2]
输出: false

注意

  • 给定树中的节点数量将在[1,100]范围内。

  • 每个节点的值将是[0,99]范围内的整数。

02 第一种解法

题目的意思是判断二叉树中的节点值是否都是一个值,为同一个值就返回true,不是就返回false

思路:使用递归,中序遍历二叉树的每个节点,存入List中,再遍历比较List中的元素是否都等于二叉树的根节点值。

public boolean isUnivalTree(TreeNode root) {
    List<Integer> list = new ArrayList<Integer>();
    helper(root, list);
    for (Integer num : list) {
        if (num != root.val) {
            return false;
        }
    }
    return true;
}

public void helper(TreeNode root, List<Integer> list) {
    if (root == null) {
        return ;
    }
    helper(root.left, list);
    list.add(root.val);
    helper(root.right, list);
}

03 第二种解法

针对第一种解法的递归方式,我们也可以换成迭代的方式,借助栈Stack来实现。

public boolean isUnivalTree2(TreeNode root) {
    List<Integer> list = new ArrayList<Integer>();
    Stack<TreeNode> stack = new Stack<TreeNode>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        list.add(node.val);
        if (node.left != null) {
            stack.push(node.left);
        }
        if (node.right != null) {
            stack.push(node.right);
        }
    }
    for (Integer num : list) {
        if (num != root.val) {
            return false;
        }
    }
    return true;
}

04 第三种解法

在第二种解法的基础上,我们可以直接判断出栈的树的节点值是否等于根节点值,省掉存入List的步骤。

public boolean isUnivalTree3(TreeNode root) {
    Stack<TreeNode> stack = new Stack<TreeNode>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        if (node.val != root.val) {
            return false;
        }
        if (node.left != null) {
            stack.push(node.left);
        }
        if (node.right != null) {
            stack.push(node.right);
        }
    }
    return true;
}

05 第四种解法

既然判断节点值是否都是同一个值,那么可以借助HashSet去重的特性,使用递归,中序遍历节点值,存入HashSet中,最后判断HashSetsize是否等于1即可。

public boolean isUnivalTree4(TreeNode root) {
    Set<Integer> set = new HashSet<Integer>();
    helper(root, set);
    return set.size() == 1;
}

public void helper(TreeNode root, Set<Integer> set) {
    if (root == null) {
        return ;
    }
    helper(root.left, set);
    set.add(root.val);
    helper(root.right, set);
}

06 第五种解法

针对第四种解法,也可以通过迭代的方式的来实现,借助栈Stack

public boolean isUnivalTree5(TreeNode root) {
    Set<Integer> set = new HashSet<Integer>();
    Stack<TreeNode> stack = new Stack<TreeNode>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        set.add(node.val);
        if (node.left != null) {
            stack.push(node.left);
        }
        if (node.right != null) {
            stack.push(node.right);
        }
    }
    return set.size() == 1;
}

07 第六种解法

我们也可以直接用递归,不借助其他的类。

public boolean isUnivalTree6(TreeNode root) {
    return help(root, root.val);            
}

public boolean help(TreeNode root, int num){
    if (root != null && root.left == null 
            && root.right == null && root.val == num) {
        return true;
    }
    if (root != null && root.left == null) {
        return root.val == num && help(root.right, num);
    }  
    if (root != null && root.right == null) {
        return root.val == num && help(root.left, num);
    }
    return root != null && root.val == num 
            && help(root.right, num) && help(root.left, num);
}

08 第七种解法

针对上面的第六种解法,我们还可以再简化下。因为题目给了二叉树节点的数量范围,root是不会为空的,等于null表示当前没有继续可以向下遍历的节点了。

public boolean isUnivalTree7(TreeNode root) {
    return helper(root, root.val);            
}

public boolean helper(TreeNode root, int num){
    if (root == null) {
        return true;
    }
    if (root.val != num) {
        return false;
    }
    return helper(root.right, num) && helper(root.left, num);
}

09 小结

算法专题目前已连续日更超过七个月,算法题文章234+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值