题目:

Given a binary tree, count the number of uni-value subtrees.

A Uni-value subtree means all nodes of the subtree have the same value.

For example:
Given binary tree,

              5
/ \
1 5
/ \ \
5 5 5

return 4.

链接: http://leetcode.com/problems/count-univalue-subtrees/

题解:

求Uni-value subtree的个数。对树来说这求count的首先思路就是递归了,不过这里要另外构造一个辅助函数来判断root为顶点的subtree是否是Uni-value subtree,假如是Uni-value的subtree,则结果可以+1,否则,我们返回递归求出的左子树的count和右节点的count。假如是Python的话可以一边计算一边返回。Java写起来可能稍微麻烦点。

Time Complexity - O(n), Space Complexity - O(n).

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int countUnivalSubtrees(TreeNode root) {
if(root == null)
return 0;
if(root.left == null && root.right == null)
return 1;
if(root.left == null) {
if(isUniValueSubtree(root))
return countUnivalSubtrees(root.right) + 1;
else
return countUnivalSubtrees(root.right);
} else if (root.right == null) {
if(isUniValueSubtree(root))
return countUnivalSubtrees(root.left) + 1;
else
return countUnivalSubtrees(root.left);
} else {
if(isUniValueSubtree(root))
return countUnivalSubtrees(root.left) + countUnivalSubtrees(root.right) + 1;
else
return countUnivalSubtrees(root.left) + countUnivalSubtrees(root.right);
}
} private boolean isUniValueSubtree(TreeNode root) {
if(root == null)
return true;
if(root.left == null && root.right == null)
return true;
else if (root.left != null && root.right != null) {
if(root.val == root.left.val && root.val == root.right.val)
return isUniValueSubtree(root.left) && isUniValueSubtree(root.right);
else
return false;
} else if (root.left == null) {
if(root.right.val == root.val)
return isUniValueSubtree(root.right);
else
return false;
} else {
if(root.left.val == root.val)
return isUniValueSubtree(root.left);
else
return false;
}
}
}

Update: 优化一下

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int countUnivalSubtrees(TreeNode root) {
if(root == null)
return 0;
if(root.left == null && root.right == null)
return 1;
int res = countUnivalSubtrees(root.left) + countUnivalSubtrees(root.right) ;
return isUniValueSubtree(root) ? res + 1 : res;
} private boolean isUniValueSubtree(TreeNode root) {
if(root == null)
return true;
if(root.left == null && root.right == null)
return true;
if(isUniValueSubtree(root.left) && isUniValueSubtree(root.right)) {
if(root.left != null && root.right != null)
return (root.left.val == root.right.val) && (root.left.val == root.val);
else if(root.left != null)
return root.left.val == root.val;
else
return root.right.val == root.val;
}
return false;
}
}

Update: 再优化一下。注意判断两个子树是否都为Uni-value subtree的时候用了 '&',这样才能判断两个条件,否则第一个条件为false时就不判断第二个了。

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private int count = 0;
public int countUnivalSubtrees(TreeNode root) {
if(root == null)
return 0;
isUniValueSubtree(root);
return count;
} private boolean isUniValueSubtree(TreeNode root) {
if(root == null)
return true; if(isUniValueSubtree(root.left) & isUniValueSubtree(root.right)) {
if(root.left != null && root.left.val != root.val)
return false;
if(root.right != null && root.right.val != root.val)
return false;
count++;
return true;
}
return false;
}
}

题外话:

这道题题号是250,马克一下。

二刷:

一刷写得比较250,现在要尝试不那么250。要做这道题我们首先要看清楚例子,以及弄明白什么是subtree。 subtree就是指,在一个tree里的某一个node,以及这个node的所有descendants.那么从题目给的例子里,我们复合条件的subtree有4个, 左边第三层里的两个"5"算其2, 右边第二层的"5 - 5",以及第三层的"5"也都算符合条件的subtree,所以我们返回4。 要注意root节点及右边第二层和第三层一起组成的"5-5-5"并不是subtree,这只能算一条root-to-leaf path。另外我们再看一个例子[1, 2, 3],这里作为leaf节点的2和3也分别都是符合条件的subtree,我们返回2。其实所有的leaf节点都是符合条件的。所以我们这道题的处理方法和https://leetcode.com/problems/balanced-binary-tree/ 有点像,都是自底向上进行判断。

  1. 这里我们先创建一个Global变量count, 也可以不用global变量而使用一个size为数组作为参数传递进辅助函数isUnival中。
  2. isUnival主要就是递归地自底向上判断tree是否为unival,也就是所有节点值均相等。有下面几种情况需要考虑
    1. root = null,这时候我们返回true。递归终止时,每个leaf节点都为true,所以null情况我们返回true
    2. 当左子树为unival并且右子树也为unival的时候
      1. 假如左右子节点都为空,则我们遇到leaf节点,合理,count++
      2. 假如左子节点或者右子节点不为空,但值又不与root的值相等时,root本身加左右子树形成的这个subtree不满足题意,我们返回false
      3. 否则,root及其descendants形成一个满足题意的subtree,我们把count++,记录下这个subtree
    3. 要注意判断左右子树是否为unival的时候,左子树和右子树都要判断,这里我们使用了一个'&'符号来避免短路条件判断。也可以分开写。

Java:

Time Complexity - O(n), Space Complexity - O(n).

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
int count = 0; public int countUnivalSubtrees(TreeNode root) {
if (root == null) return 0;
isUnival(root);
return count;
} private boolean isUnival(TreeNode root) {
if (root == null) return true;
if (isUnival(root.left) & isUnival(root.right)) {
if (root.left != null && root.left.val != root.val) return false;
if (root.right != null && root.right.val != root.val) return false;
count++;
return true;
}
return false;
}
}

Reference:

https://leetcode.com/discuss/66805/my-java-solution-using-a-boolean-helper-function

https://leetcode.com/discuss/68057/very-easy-java-solution-post-order-recursion

https://leetcode.com/discuss/63286/7-line-accepted-code-in-java

https://leetcode.com/discuss/52210/c-one-pass-recursive-solution

https://leetcode.com/discuss/50241/recursive-java-solution-with-explanation

https://leetcode.com/discuss/50357/my-concise-java-solution

https://leetcode.com/discuss/50420/java-11-lines-added

https://leetcode.com/discuss/68057/very-easy-java-solution-post-order-recursion

https://github.com/google/google-java-format

https://leetcode.com/discuss/55213/my-ac-java-code

https://leetcode.com/discuss/53431/java-solution-with-dfs

https://leetcode.com/discuss/50452/ac-clean-java-solution

https://en.wikipedia.org/wiki/Tree_(data_structure)

https://leetcode.com/problems/balanced-binary-tree/

250. Count Univalue Subtrees的更多相关文章

  1. [LeetCode#250] Count Univalue Subtrees

    Problem: Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all ...

  2. [leetcode]250. Count Univalue Subtrees统计节点值相同的子树

    Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of ...

  3. [LeetCode] 250. Count Univalue Subtrees 计算唯一值子树的个数

    Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of ...

  4. [LC] 250. Count Univalue Subtrees

    Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of ...

  5. [Locked] Count Univalue Subtrees

    Count Univalue Subtrees Given a binary tree, count the number of uni-value subtrees. A Uni-value sub ...

  6. [LeetCode] Count Univalue Subtrees 计数相同值子树的个数

    Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of ...

  7. [Swift]LeetCode250.计数相同值子树的个数 $ Count Univalue Subtrees

    Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of ...

  8. LeetCode-Count Univalue Subtrees

    Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of ...

  9. <Tree> 298 250 366 199(高频) 98(高频)

    298. Binary Tree Longest Consecutive Sequence 先序遍历,根左右.如果该节点的 value == 父节点value + 1, 则长度+1; 否则重置为1. ...

随机推荐

  1. Android之“Unfortunately,xxx has stopped!”

    初学Android遇到Unfortunately,xxx has stopped!真是一件让人头疼的事情,下面就遇到的两种可能情况给出解决方案.通常遇到的情况在于由一个Activity跳转至另一个Ac ...

  2. nginx服务器绑定域名和设置根目录

    首先进入nginx安装目录的配置目录conf,然后执行 vi conf/nginx.conf 打开nginx的配置文件,找到并修改红字部分 server { listen default_server ...

  3. java之jar命令详解

    1. JAR 文件包 JAR 文件就是 Java Archive File,顾名思意,它的应用是与 Java 息息相关的,是 Java 的一种文档格式.JAR 文件非常类似 ZIP 文件——准确的说, ...

  4. [ios]ipad下的splitViewController 让你的APP看起来酷酷的!

    在ipad下可以使用splitViewController splitViewController下包含两个viewController 这是一种将屏幕一分为二的方式. 在水平状态下会出现成两个左右两 ...

  5. 从零开始学ios开发(九):Swapping Views

    这篇的内容是切换Views,也是上一篇中提到的第三种当iphone发生旋转后改变布局的方式,先回顾一下上一篇中提到的三种方式 1.使用Autosizing 2.写code 3.重新弄个View,替换原 ...

  6. Android 开发 res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)

    (1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854) (2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x ...

  7. 使用GitHub建立自己的个人主页

    1.建仓库 在自己的库里建一个hujun123qwe.github.io的库 即可以使用这个名字当网址访问. 2.写内容 在库里建一个首页文件 index.html 这个个人主页只支持静态的内容,像p ...

  8. iOS开发之静态库的制作

    当你需要和别人分享代码,但又不想让别人看到你内部的实现时就需要制作静态库,通常用于第三方SDK 下面就分享一下制作静态库(.a)的过程: 1.打开Xcode,新建workspace 2.随便给work ...

  9. PAT-乙级-1054. 求平均值 (20)

    1054. 求平均值 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题的基本要求非常简单:给定N个实 ...

  10. C/C++框架和库

    http://blog.csdn.net/xiaoxiaoyeyaya/article/details/42541419 值得学习的C语言开源项目 - 1. Webbench Webbench是一个在 ...