📌  相关文章
📜  删除长度小于 K 的根到叶路径上的节点

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

删除长度小于 K 的根到叶路径上的节点

给定一棵二叉树和一个数 k,删除仅位于根到叶路径长度小于 k 的所有节点。如果节点 X 位于多个从根到叶的路径上,并且任何路径的路径长度 >= k,则 X 不会从二叉树中删除。换句话说,如果通过它的所有路径的长度都小于 k,则删除一个节点。
考虑以下示例二叉树

1
           /      \
         2          3
      /     \         \
    4         5        6
  /                   /
 7                   8 
Input: Root of above Binary Tree
       k = 4

Output: The tree should be changed to following  
           1
        /     \
      2          3
     /             \
   4                 6
 /                  /
7                  8
There are 3 paths 
i) 1->2->4->7      path length = 4
ii) 1->2->5        path length = 3
iii) 1->3->6->8    path length = 4 
There is only one path " 1->2->5 " of length smaller than 4.  
The node 5 is the only node that lies only on this path, so 
node 5 is removed.
Nodes 2 and 1 are not removed as they are parts of other paths
of length 4 as well.

If k is 5 or greater than 5, then whole tree is deleted. 

If k is 3 or less than 3, then nothing is deleted.

我们强烈建议您最小化您的浏览器并先自己尝试
这里的想法是使用树的后序遍历。在删除一个节点之前,我们需要检查该节点在较短路径中的所有子节点是否已被删除。
有2种情况:
i) 该节点成为叶节点,在这种情况下需要将其删除。
ii) 该节点在路径长度 >= k 的路径上有其他子节点。在这种情况下,它不需要被删除。
上述方法的实现如下:

C++
// C++ program to remove nodes on root to leaf paths of length < K
#include
using namespace std;
 
struct Node
{
    int data;
    Node *left, *right;
};
 
//New node of a tree
Node *newNode(int data)
{
    Node *node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return node;
}
 
// Utility method that actually removes the nodes which are not
// on the pathLen >= k. This method can change the root as well.
Node *removeShortPathNodesUtil(Node *root, int level, int k)
{
    //Base condition
    if (root == NULL)
        return NULL;
 
    // Traverse the tree in postorder fashion so that if a leaf
    // node path length is shorter than k, then that node and
    // all of its descendants till the node which are not
    // on some other path are removed.
    root->left = removeShortPathNodesUtil(root->left, level + 1, k);
    root->right = removeShortPathNodesUtil(root->right, level + 1, k);
 
    // If root is a leaf node and it's level is less than k then
    // remove this node.
    // This goes up and check for the ancestor nodes also for the
    // same condition till it finds a node which is a part of other
    // path(s) too.
    if (root->left == NULL && root->right == NULL && level < k)
    {
        delete root;
        return NULL;
    }
 
    // Return root;
    return root;
}
 
// Method which calls the utility method to remove the short path
// nodes.
Node *removeShortPathNodes(Node *root, int k)
{
    int pathLen = 0;
    return removeShortPathNodesUtil(root, 1, k);
}
 
//Method to print the tree in inorder fashion.
void printInorder(Node *root)
{
    if (root)
    {
        printInorder(root->left);
        cout << root->data << " ";
        printInorder(root->right);
    }
}
 
// Driver method.
int main()
{
    int k = 4;
    Node *root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->left->left->left = newNode(7);
    root->right->right = newNode(6);
    root->right->right->left = newNode(8);
    cout << "Inorder Traversal of Original tree" << endl;
    printInorder(root);
    cout << endl;
    cout << "Inorder Traversal of Modified tree" << endl;
    Node *res = removeShortPathNodes(root, k);
    printInorder(res);
    return 0;
}


Java
// Java program to remove nodes on root to leaf paths of length < k
  
/* 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 BinaryTree
{
    Node root;
  
    // Utility method that actually removes the nodes which are not
    // on the pathLen >= k. This method can change the root as well.
    Node removeShortPathNodesUtil(Node node, int level, int k)
    {
        //Base condition
        if (node == null)
            return null;
             
        // Traverse the tree in postorder fashion so that if a leaf
        // node path length is shorter than k, then that node and
        // all of its descendants till the node which are not
        // on some other path are removed.
        node.left = removeShortPathNodesUtil(node.left, level + 1, k);
        node.right = removeShortPathNodesUtil(node.right, level + 1, k);
  
        // If root is a leaf node and it's level is less than k then
        // remove this node.
        // This goes up and check for the ancestor nodes also for the
        // same condition till it finds a node which is a part of other
        // path(s) too.
        if (node.left == null && node.right == null && level < k)
            return null;
  
        // Return root;
        return node;
    }
  
    // Method which calls the utility method to remove the short path
    // nodes.
    Node removeShortPathNodes(Node node, int k)
    {
        int pathLen = 0;
        return removeShortPathNodesUtil(node, 1, k);
    }
  
    //Method to print the tree in inorder fashion.
    void printInorder(Node node)
    {
        if (node != null)
        {
            printInorder(node.left);
            System.out.print(node.data + " ");
            printInorder(node.right);
        }
    }
  
    // Driver program to test for samples
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
        int k = 4;
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
        tree.root.left.left.left = new Node(7);
        tree.root.right.right = new Node(6);
        tree.root.right.right.left = new Node(8);
        System.out.println("The inorder traversal of original tree is : ");
        tree.printInorder(tree.root);
        Node res = tree.removeShortPathNodes(tree.root, k);
        System.out.println("");
        System.out.println("The inorder traversal of modified tree is : ");
        tree.printInorder(res);
    }
}
  
// This code has been contributed by Mayank Jaiswal


Python3
# Python3 program to remove nodes on root
# to leaf paths of length < K
 
# New node of a tree
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
         
# Utility method that actually removes
# the nodes which are not on the pathLen >= k.
# This method can change the root as well.
def removeShortPathNodesUtil(root, level, k) :
 
    # Base condition
    if (root == None) :
        return None
 
    # Traverse the tree in postorder fashion
    # so that if a leaf node path length is
    # shorter than k, then that node and all
    # of its descendants till the node which 
    # are not on some other path are removed.
    root.left = removeShortPathNodesUtil(root.left,
                                         level + 1, k)
    root.right = removeShortPathNodesUtil(root.right,
                                          level + 1, k)
 
    # If root is a leaf node and it's level
    # is less than k then remove this node.
    # This goes up and check for the ancestor
    # nodes also for the same condition till
    # it finds a node which is a part of other
    # path(s) too.
    if (root.left == None and
        root.right == None and level < k) :
        return None
     
    # Return root
    return root
 
# Method which calls the utility method
# to remove the short path nodes.
def removeShortPathNodes(root, k) :
    pathLen = 0
    return removeShortPathNodesUtil(root, 1, k)
 
# Method to print the tree in
# inorder fashion.
def prInorder(root) :
 
    if (root) :
     
        prInorder(root.left)
        print(root.data, end = " " )
        prInorder(root.right)
     
# Driver Code
if __name__ == '__main__':
    k = 4
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.left.right = newNode(5)
    root.left.left.left = newNode(7)
    root.right.right = newNode(6)
    root.right.right.left = newNode(8)
    print("Inorder Traversal of Original tree" )
    prInorder(root)
    print()
    print("Inorder Traversal of Modified tree" )
    res = removeShortPathNodes(root, k)
    prInorder(res)
 
# This code is contributed
# by SHUBHAMSINGH10


C#
using System;
 
// C# program to remove nodes on root to leaf paths of length < k
 
/* 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 BinaryTree
{
    public Node root;
 
    // Utility method that actually removes the nodes which are not
    // on the pathLen >= k. This method can change the root as well.
    public virtual Node removeShortPathNodesUtil(Node node, int level, int k)
    {
        //Base condition
        if (node == null)
        {
            return null;
        }
 
        // Traverse the tree in postorder fashion so that if a leaf
        // node path length is shorter than k, then that node and
        // all of its descendants till the node which are not
        // on some other path are removed.
        node.left = removeShortPathNodesUtil(node.left, level + 1, k);
        node.right = removeShortPathNodesUtil(node.right, level + 1, k);
 
        // If root is a leaf node and it's level is less than k then
        // remove this node.
        // This goes up and check for the ancestor nodes also for the
        // same condition till it finds a node which is a part of other
        // path(s) too.
        if (node.left == null && node.right == null && level < k)
        {
            return null;
        }
 
        // Return root;
        return node;
    }
 
    // Method which calls the utility method to remove the short path
    // nodes.
    public virtual Node removeShortPathNodes(Node node, int k)
    {
        int pathLen = 0;
        return removeShortPathNodesUtil(node, 1, k);
    }
 
    //Method to print the tree in inorder fashion.
    public virtual void printInorder(Node node)
    {
        if (node != null)
        {
            printInorder(node.left);
            Console.Write(node.data + " ");
            printInorder(node.right);
        }
    }
 
    // Driver program to test for samples
    public static void Main(string[] args)
    {
        BinaryTree tree = new BinaryTree();
        int k = 4;
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
        tree.root.left.left.left = new Node(7);
        tree.root.right.right = new Node(6);
        tree.root.right.right.left = new Node(8);
        Console.WriteLine("The inorder traversal of original tree is : ");
        tree.printInorder(tree.root);
        Node res = tree.removeShortPathNodes(tree.root, k);
        Console.WriteLine("");
        Console.WriteLine("The inorder traversal of modified tree is : ");
        tree.printInorder(res);
    }
}
 
  //  This code is contributed by Shrikant13


Javascript


输出:

Inorder Traversal of Original tree
7 4 2 5 1 3 8 6
Inorder Traversal of Modified tree
7 4 2 1 3 8 6

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