📜  查找单值子树的计数

📅  最后修改于: 2022-05-13 01:57:17.707000             🧑  作者: Mango

查找单值子树的计数

给定一棵二叉树,编写一个程序来计算单值子树的数量。单值子树是所有节点都具有相同值的子树。预期时间复杂度为 O(n)。
例子:

Input: root of below tree
              5
             / \
            1   5
           / \   \
          5   5   5
Output: 4
There are 4 subtrees with single values.


Input: root of below tree
              5
             / \
            4   5
           / \   \
          4   4   5                
Output: 5
There are five subtrees with single values.

我们强烈建议您最小化您的浏览器并首先自己尝试。
一个简单的解决方案是遍历树。对于每个遍历的节点,检查该节点下的所有值是否相同。如果相同,则增加计数。该解决方案的时间复杂度为 O(n 2 )。
一个有效的解决方案是以自下而上的方式遍历树。对于每个访问过的子树,如果其下的子树是单值并递增计数,则返回 true。所以想法是在递归调用中使用count作为参考参数,并使用返回值来判断左右子树是否是单值的。
下面是上述想法的实现。

C++
// C++ program to find count of single valued subtrees
#include
using namespace std;
 
// A Tree node
struct Node
{
    int data;
    struct Node* left, *right;
};
 
// Utility function to create a new node
Node* newNode(int data)
{
    Node* temp = new Node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return (temp);
}
 
// This function increments count by number of single
// valued subtrees under root. It returns true if subtree
// under root is Singly, else false.
bool countSingleRec(Node* root, int &count)
{
    // Return false to indicate NULL
    if (root == NULL)
       return true;
 
    // Recursively count in left and right subtrees also
    bool left = countSingleRec(root->left, count);
    bool right = countSingleRec(root->right, count);
 
    // If any of the subtrees is not singly, then this
    // cannot be singly.
    if (left == false || right == false)
       return false;
 
    // If left subtree is singly and non-empty, but data
    // doesn't match
    if (root->left && root->data != root->left->data)
        return false;
 
    // Same for right subtree
    if (root->right && root->data != root->right->data)
        return false;
 
    // If none of the above conditions is true, then
    // tree rooted under root is single valued, increment
    // count and return true.
    count++;
    return true;
}
 
// This function mainly calls countSingleRec()
// after initializing count as 0
int countSingle(Node* root)
{
    // Initialize result
    int count = 0;
 
    // Recursive function to count
    countSingleRec(root, count);
 
    return count;
}
 
// Driver program to test
int main()
{
    /* Let us construct the below tree
            5
          /   \
        4      5
      /  \      \
     4    4      5 */
    Node* root        = newNode(5);
    root->left        = newNode(4);
    root->right       = newNode(5);
    root->left->left  = newNode(4);
    root->left->right = newNode(4);
    root->right->right = newNode(5);
 
    cout << "Count of Single Valued Subtrees is "
         << countSingle(root);
    return 0;
}


Java
// Java program to find count of single valued subtrees
  
/* Class containing left and right child of current
 node and key value*/
class Node
{
    int data;
    Node left, right;
  
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
class Count
{
    int count = 0;
}
  
class BinaryTree
{
    Node root; 
    Count ct = new Count();
      
    // This function increments count by number of single
    // valued subtrees under root. It returns true if subtree
    // under root is Singly, else false.
    boolean countSingleRec(Node node, Count c)
    {
        // Return false to indicate NULL
        if (node == null)
            return true;
          
        // Recursively count in left and right subtrees also
        boolean left = countSingleRec(node.left, c);
        boolean right = countSingleRec(node.right, c);
  
        // If any of the subtrees is not singly, then this
        // cannot be singly.
        if (left == false || right == false)
            return false;
  
        // If left subtree is singly and non-empty, but data
        // doesn't match
        if (node.left != null && node.data != node.left.data)
            return false;
  
        // Same for right subtree
        if (node.right != null && node.data != node.right.data)
            return false;
  
        // If none of the above conditions is true, then
        // tree rooted under root is single valued, increment
        // count and return true.
        c.count++;
        return true;
    }
  
    // This function mainly calls countSingleRec()
    // after initializing count as 0
    int countSingle()
    {
        return countSingle(root);
    }
  
    int countSingle(Node node)
    {
        // Recursive function to count
        countSingleRec(node, ct);
        return ct.count;
    }
  
    // Driver program to test above functions
    public static void main(String args[])
    {
           /* Let us construct the below tree
                5
              /   \
            4      5
          /  \      \
         4    4      5 */
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(5);
        tree.root.left = new Node(4);
        tree.root.right = new Node(5);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(4);
        tree.root.right.right = new Node(5);
  
        System.out.println("The count of single valued sub trees is : "
                                            + tree.countSingle());
    }
}
  
// This code has been contributed by Mayank Jaiswal


Python3
# Python program to find the count of single valued subtrees
 
# Node Structure
class Node:
    # Utility function to create a new node
    def __init__(self ,data):
        self.data = data
        self.left = None
        self.right = None
 
 
# This function increments count by number of single
# valued subtrees under root. It returns true if subtree
# under root is Singly, else false.
def countSingleRec(root , count):
    # Return False to indicate None
    if root is None :
        return True
 
    # Recursively count in left and right subtrees also
    left = countSingleRec(root.left , count)
    right = countSingleRec(root.right , count)
     
    # If any of the subtrees is not singly, then this
    # cannot be singly
    if left == False or right  == False :
        return False
     
    # If left subtree is singly and non-empty , but data
    # doesn't match
    if root.left and root.data != root.left.data:
        return False
 
    # same for right subtree
    if root.right and root.data != root.right.data:
        return False
 
    # If none of the above conditions is True, then
    # tree rooted under root is single valued,increment
    # count and return true
    count[0] += 1
    return True
 
 
# This function mainly class countSingleRec()
# after initializing count as 0
def countSingle(root):
    # initialize result
    count = [0]
 
    # Recursive function to count
    countSingleRec(root , count)
 
    return count[0]
 
 
# Driver program to test
 
"""Let us construct the below tree
            5
          /   \
        4       5
       /  \      \
      4    4      5
"""
root = Node(5)
root.left = Node(4)
root.right = Node(5)
root.left.left = Node(4)
root.left.right = Node(4)
root.right.right = Node(5)
countSingle(root)
print ("Count of Single Valued Subtrees is" , countSingle(root))
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#
using System;
 
// C# program to find count of single valued subtrees
 
/* Class containing left and right child of current 
 node and key value*/
public class Node
{
    public int data;
    public Node left, right;
 
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
public class Count
{
    public int count = 0;
}
 
public class BinaryTree
{
    public Node root;
    public Count ct = new Count();
 
    // This function increments count by number of single 
    // valued subtrees under root. It returns true if subtree 
    // under root is Singly, else false.
    public virtual bool countSingleRec(Node node, Count c)
    {
        // Return false to indicate NULL
        if (node == null)
        {
            return true;
        }
 
        // Recursively count in left and right subtrees also
        bool left = countSingleRec(node.left, c);
        bool right = countSingleRec(node.right, c);
 
        // If any of the subtrees is not singly, then this
        // cannot be singly.
        if (left == false || right == false)
        {
            return false;
        }
 
        // If left subtree is singly and non-empty, but data
        // doesn't match
        if (node.left != null && node.data != node.left.data)
        {
            return false;
        }
 
        // Same for right subtree
        if (node.right != null && node.data != node.right.data)
        {
            return false;
        }
 
        // If none of the above conditions is true, then
        // tree rooted under root is single valued, increment
        // count and return true.
        c.count++;
        return true;
    }
 
    // This function mainly calls countSingleRec()
    // after initializing count as 0
    public virtual int countSingle()
    {
        return countSingle(root);
    }
 
    public virtual int countSingle(Node node)
    {
        // Recursive function to count
        countSingleRec(node, ct);
        return ct.count;
    }
 
    // Driver program to test above functions
    public static void Main(string[] args)
    {
           /* Let us construct the below tree
                5
              /   \
            4      5
          /  \      \
         4    4      5 */
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(5);
        tree.root.left = new Node(4);
        tree.root.right = new Node(5);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(4);
        tree.root.right.right = new Node(5);
 
        Console.WriteLine("The count of single valued sub trees is : " + tree.countSingle());
    }
}
 
  // This code is contributed by Shrikant13


Javascript


输出:

Count of Single Valued Subtrees is 5

该解决方案的时间复杂度为 O(n),其中 n 是给定二叉树中的节点数。