检查删除边是否可以将二叉树分成两半
给定一棵二叉树,找出是否存在一条边,其移除会创建两棵大小相等的树。
例子:
Input : root of following tree
5
/ \
1 6
/ / \
3 7 4
Output : true
Removing edge 5-6 creates two trees of equal size
Input : root of following tree
5
/ \
1 6
/ \
7 4
/ \ \
3 2 8
Output : false
There is no edge whose removal creates two trees
of equal size.
资料来源- Kshitij IIT KGP
方法1(简单)
首先计算整个树中的节点数。设所有节点的计数为 n。现在遍历树并为每个节点找到以该节点为根的子树的大小。设子树大小为 s。如果 ns 等于 s,则返回 true,否则返回 false。
C++
// C++ program to check if there exist an edge whose
// removal creates two trees of same size
#include
using namespace std;
struct Node
{
int data;
struct Node* left, *right;
};
// utility function to create a new node
struct Node* newNode(int x)
{
struct Node* temp = new Node;
temp->data = x;
temp->left = temp->right = NULL;
return temp;
};
// To calculate size of tree with given root
int count(Node* root)
{
if (root==NULL)
return 0;
return count(root->left) + count(root->right) + 1;
}
// This function returns true if there is an edge
// whose removal can divide the tree in two halves
// n is size of tree
bool checkRec(Node* root, int n)
{
// Base cases
if (root ==NULL)
return false;
// Check for root
if (count(root) == n-count(root))
return true;
// Check for rest of the nodes
return checkRec(root->left, n) ||
checkRec(root->right, n);
}
// This function mainly uses checkRec()
bool check(Node *root)
{
// Count total nodes in given tree
int n = count(root);
// Now recursively check all nodes
return checkRec(root, n);
}
// Driver code
int main()
{
struct Node* root = newNode(5);
root->left = newNode(1);
root->right = newNode(6);
root->left->left = newNode(3);
root->right->left = newNode(7);
root->right->right = newNode(4);
check(root)? printf("YES") : printf("NO");
return 0;
}
Java
// Java program to check if there exist an edge whose
// removal creates two trees of same size
class Node
{
int key;
Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
class BinaryTree
{
Node root;
// To calculate size of tree with given root
int count(Node node)
{
if (node == null)
return 0;
return count(node.left) + count(node.right) + 1;
}
// This function returns true if there is an edge
// whose removal can divide the tree in two halves
// n is size of tree
boolean checkRec(Node node, int n)
{
// Base cases
if (node == null)
return false;
// Check for root
if (count(node) == n - count(node))
return true;
// Check for rest of the nodes
return checkRec(node.left, n)
|| checkRec(node.right, n);
}
// This function mainly uses checkRec()
boolean check(Node node)
{
// Count total nodes in given tree
int n = count(node);
// Now recursively check all nodes
return checkRec(node, n);
}
// Driver code
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(5);
tree.root.left = new Node(1);
tree.root.right = new Node(6);
tree.root.left.left = new Node(3);
tree.root.right.left = new Node(7);
tree.root.right.right = new Node(4);
if(tree.check(tree.root)==true)
System.out.println("YES");
else
System.out.println("NO");
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# Python3 program to check if there
# exist an edge whose removal creates
# two trees of same size
# utility function to create a new node
class newNode:
def __init__(self, x):
self.data = x
self.left = self.right = None
# To calculate size of tree
# with given root
def count(root):
if (root == None):
return 0
return (count(root.left) +
count(root.right) + 1)
# This function returns true if there
# is an edge whose removal can divide
# the tree in two halves n is size of tree
def checkRec(root, n):
# Base cases
if (root == None):
return False
# Check for root
if (count(root) == n - count(root)):
return True
# Check for rest of the nodes
return (checkRec(root.left, n) or
checkRec(root.right, n))
# This function mainly uses checkRec()
def check(root):
# Count total nodes in given tree
n = count(root)
# Now recursively check all nodes
return checkRec(root, n)
# Driver code
if __name__ == '__main__':
root = newNode(5)
root.left = newNode(1)
root.right = newNode(6)
root.left.left = newNode(3)
root.right.left = newNode(7)
root.right.right = newNode(4)
if check(root):
print("YES")
else:
print("NO")
# This code is contributed by PranchalK
C#
// C# program to check if there exist
// an edge whose removal creates two
// trees of same size
using System;
public class Node
{
public int key;
public Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
class GFG
{
public Node root;
// To calculate size of tree with given root
public virtual int count(Node node)
{
if (node == null)
{
return 0;
}
return count(node.left) +
count(node.right) + 1;
}
// This function returns true if there
// is an edge whose removal can divide
// the tree in two halves n is size of tree
public virtual bool checkRec(Node node, int n)
{
// Base cases
if (node == null)
{
return false;
}
// Check for root
if (count(node) == n - count(node))
{
return true;
}
// Check for rest of the nodes
return checkRec(node.left, n) ||
checkRec(node.right, n);
}
// This function mainly uses checkRec()
public virtual bool check(Node node)
{
// Count total nodes in given tree
int n = count(node);
// Now recursively check all nodes
return checkRec(node, n);
}
// Driver code
public static void Main(string[] args)
{
GFG tree = new GFG();
tree.root = new Node(5);
tree.root.left = new Node(1);
tree.root.right = new Node(6);
tree.root.left.left = new Node(3);
tree.root.right.left = new Node(7);
tree.root.right.right = new Node(4);
if (tree.check(tree.root) == true)
{
Console.WriteLine("YES");
}
else
{
Console.WriteLine("NO");
}
}
}
// This code is contributed by Shrikant13
Javascript
C++
// C++ program to check if there exist an edge whose
// removal creates two trees of same size
#include
using namespace std;
struct Node
{
int data;
struct Node* left, *right;
};
// utility function to create a new node
struct Node* newNode(int x)
{
struct Node* temp = new Node;
temp->data = x;
temp->left = temp->right = NULL;
return temp;
};
// To calculate size of tree with given root
int count(Node* root)
{
if (root==NULL)
return 0;
return count(root->left) + count(root->right) + 1;
}
// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
int checkRec(Node* root, int n, bool &res)
{
// Base case
if (root == NULL)
return 0;
// Compute sizes of left and right children
int c = checkRec(root->left, n, res) + 1 +
checkRec(root->right, n, res);
// If required property is true for current node
// set "res" as true
if (c == n-c)
res = true;
// Return size
return c;
}
// This function mainly uses checkRec()
bool check(Node *root)
{
// Count total nodes in given tree
int n = count(root);
// Initialize result and recursively check all nodes
bool res = false;
checkRec(root, n, res);
return res;
}
// Driver code
int main()
{
struct Node* root = newNode(5);
root->left = newNode(1);
root->right = newNode(6);
root->left->left = newNode(3);
root->right->left = newNode(7);
root->right->right = newNode(4);
check(root)? printf("YES") : printf("NO");
return 0;
}
Java
// Java program to check if there exist an edge whose
// removal creates two trees of same size
class Node
{
int key;
Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
class Res
{
boolean res = false;
}
class BinaryTree
{
Node root;
// To calculate size of tree with given root
int count(Node node)
{
if (node == null)
return 0;
return count(node.left) + count(node.right) + 1;
}
// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
int checkRec(Node root, int n, Res res)
{
// Base case
if (root == null)
return 0;
// Compute sizes of left and right children
int c = checkRec(root.left, n, res) + 1
+ checkRec(root.right, n, res);
// If required property is true for current node
// set "res" as true
if (c == n - c)
res.res = true;
// Return size
return c;
}
// This function mainly uses checkRec()
boolean check(Node root)
{
// Count total nodes in given tree
int n = count(root);
// Initialize result and recursively check all nodes
Res res = new Res();
checkRec(root, n, res);
return res.res;
}
// Driver code
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(5);
tree.root.left = new Node(1);
tree.root.right = new Node(6);
tree.root.left.left = new Node(3);
tree.root.right.left = new Node(7);
tree.root.right.right = new Node(4);
if (tree.check(tree.root) == true)
System.out.println("YES");
else
System.out.println("NO");
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# Python3 program to check if there exist
# an edge whose removal creates two trees
# of same size
class Node:
def __init__(self, x):
self.key = x
self.left = None
self.right = None
# To calculate size of tree with
# given root
def count(node):
if (node == None):
return 0
return (count(node.left) +
count(node.right) + 1)
# This function returns size of tree rooted
# with given root. It also set "res" as true
# if there is an edge whose removal divides
# tree in two halves.n is size of tree
def checkRec(root, n):
global res
# Base case
if (root == None):
return 0
# Compute sizes of left and right children
c = (checkRec(root.left, n) + 1 +
checkRec(root.right, n))
# If required property is true for
# current node set "res" as true
if (c == n - c):
res = True
# Return size
return c
# This function mainly uses checkRec()
def check(root):
# Count total nodes in given tree
n = count(root)
# Initialize result and recursively
# check all nodes
# bool res = false;
checkRec(root, n)
# Driver code
if __name__ == '__main__':
res = False
root = Node(5)
root.left = Node(1)
root.right = Node(6)
root.left.left = Node(3)
root.right.left = Node(7)
root.right.right = Node(4)
check(root)
if res:
print("YES")
else:
print("NO")
# This code is contributed by mohit kumar 29
C#
// C# program to check if there exist an edge whose
// removal creates two trees of same size
using System;
public class Node
{
public int key;
public Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
public class Res
{
public bool res = false;
}
public class BinaryTree
{
public Node root;
// To calculate size of tree with given root
public virtual int count(Node node)
{
if (node == null)
{
return 0;
}
return count(node.left) + count(node.right) + 1;
}
// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
public virtual int checkRec(Node root, int n, Res res)
{
// Base case
if (root == null)
{
return 0;
}
// Compute sizes of left and right children
int c = checkRec(root.left, n, res) + 1 + checkRec(root.right, n, res);
// If required property is true for current node
// set "res" as true
if (c == n - c)
{
res.res = true;
}
// Return size
return c;
}
// This function mainly uses checkRec()
public virtual bool check(Node root)
{
// Count total nodes in given tree
int n = count(root);
// Initialize result and recursively check all nodes
Res res = new Res();
checkRec(root, n, res);
return res.res;
}
// Driver code
public static void Main(string[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(5);
tree.root.left = new Node(1);
tree.root.right = new Node(6);
tree.root.left.left = new Node(3);
tree.root.right.left = new Node(7);
tree.root.right.right = new Node(4);
if (tree.check(tree.root) == true)
{
Console.WriteLine("YES");
}
else
{
Console.WriteLine("NO");
}
}
}
// This code is contributed by Shrikant13
Javascript
输出 :
YES
上述解决方案的时间复杂度为 O(n 2 ),其中 n 是给定二叉树中的节点数。
方法二(高效)
我们可以在 O(n) 时间内找到解决方案。这个想法是以自下而上的方式遍历树,并在遍历时不断更新大小并不断检查是否有一个节点遵循所需的属性。
下面是上述想法的实现。
C++
// C++ program to check if there exist an edge whose
// removal creates two trees of same size
#include
using namespace std;
struct Node
{
int data;
struct Node* left, *right;
};
// utility function to create a new node
struct Node* newNode(int x)
{
struct Node* temp = new Node;
temp->data = x;
temp->left = temp->right = NULL;
return temp;
};
// To calculate size of tree with given root
int count(Node* root)
{
if (root==NULL)
return 0;
return count(root->left) + count(root->right) + 1;
}
// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
int checkRec(Node* root, int n, bool &res)
{
// Base case
if (root == NULL)
return 0;
// Compute sizes of left and right children
int c = checkRec(root->left, n, res) + 1 +
checkRec(root->right, n, res);
// If required property is true for current node
// set "res" as true
if (c == n-c)
res = true;
// Return size
return c;
}
// This function mainly uses checkRec()
bool check(Node *root)
{
// Count total nodes in given tree
int n = count(root);
// Initialize result and recursively check all nodes
bool res = false;
checkRec(root, n, res);
return res;
}
// Driver code
int main()
{
struct Node* root = newNode(5);
root->left = newNode(1);
root->right = newNode(6);
root->left->left = newNode(3);
root->right->left = newNode(7);
root->right->right = newNode(4);
check(root)? printf("YES") : printf("NO");
return 0;
}
Java
// Java program to check if there exist an edge whose
// removal creates two trees of same size
class Node
{
int key;
Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
class Res
{
boolean res = false;
}
class BinaryTree
{
Node root;
// To calculate size of tree with given root
int count(Node node)
{
if (node == null)
return 0;
return count(node.left) + count(node.right) + 1;
}
// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
int checkRec(Node root, int n, Res res)
{
// Base case
if (root == null)
return 0;
// Compute sizes of left and right children
int c = checkRec(root.left, n, res) + 1
+ checkRec(root.right, n, res);
// If required property is true for current node
// set "res" as true
if (c == n - c)
res.res = true;
// Return size
return c;
}
// This function mainly uses checkRec()
boolean check(Node root)
{
// Count total nodes in given tree
int n = count(root);
// Initialize result and recursively check all nodes
Res res = new Res();
checkRec(root, n, res);
return res.res;
}
// Driver code
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(5);
tree.root.left = new Node(1);
tree.root.right = new Node(6);
tree.root.left.left = new Node(3);
tree.root.right.left = new Node(7);
tree.root.right.right = new Node(4);
if (tree.check(tree.root) == true)
System.out.println("YES");
else
System.out.println("NO");
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# Python3 program to check if there exist
# an edge whose removal creates two trees
# of same size
class Node:
def __init__(self, x):
self.key = x
self.left = None
self.right = None
# To calculate size of tree with
# given root
def count(node):
if (node == None):
return 0
return (count(node.left) +
count(node.right) + 1)
# This function returns size of tree rooted
# with given root. It also set "res" as true
# if there is an edge whose removal divides
# tree in two halves.n is size of tree
def checkRec(root, n):
global res
# Base case
if (root == None):
return 0
# Compute sizes of left and right children
c = (checkRec(root.left, n) + 1 +
checkRec(root.right, n))
# If required property is true for
# current node set "res" as true
if (c == n - c):
res = True
# Return size
return c
# This function mainly uses checkRec()
def check(root):
# Count total nodes in given tree
n = count(root)
# Initialize result and recursively
# check all nodes
# bool res = false;
checkRec(root, n)
# Driver code
if __name__ == '__main__':
res = False
root = Node(5)
root.left = Node(1)
root.right = Node(6)
root.left.left = Node(3)
root.right.left = Node(7)
root.right.right = Node(4)
check(root)
if res:
print("YES")
else:
print("NO")
# This code is contributed by mohit kumar 29
C#
// C# program to check if there exist an edge whose
// removal creates two trees of same size
using System;
public class Node
{
public int key;
public Node left, right;
public Node(int key)
{
this.key = key;
left = right = null;
}
}
public class Res
{
public bool res = false;
}
public class BinaryTree
{
public Node root;
// To calculate size of tree with given root
public virtual int count(Node node)
{
if (node == null)
{
return 0;
}
return count(node.left) + count(node.right) + 1;
}
// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
public virtual int checkRec(Node root, int n, Res res)
{
// Base case
if (root == null)
{
return 0;
}
// Compute sizes of left and right children
int c = checkRec(root.left, n, res) + 1 + checkRec(root.right, n, res);
// If required property is true for current node
// set "res" as true
if (c == n - c)
{
res.res = true;
}
// Return size
return c;
}
// This function mainly uses checkRec()
public virtual bool check(Node root)
{
// Count total nodes in given tree
int n = count(root);
// Initialize result and recursively check all nodes
Res res = new Res();
checkRec(root, n, res);
return res.res;
}
// Driver code
public static void Main(string[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(5);
tree.root.left = new Node(1);
tree.root.right = new Node(6);
tree.root.left.left = new Node(3);
tree.root.right.left = new Node(7);
tree.root.right.right = new Node(4);
if (tree.check(tree.root) == true)
{
Console.WriteLine("YES");
}
else
{
Console.WriteLine("NO");
}
}
}
// This code is contributed by Shrikant13
Javascript
输出 :
YES