BST más grande en un árbol binario | conjunto 2

Dado un árbol binario, escriba una función que devuelva el tamaño del subárbol más grande que también es un árbol de búsqueda binaria (BST). Si el árbol binario completo es BST, devuelve el tamaño de todo el árbol.
Ejemplos: 
 

Input: 
      5
    /  \
   2    4
 /  \
1    3

Output: 3 
The following subtree is the 
maximum size BST subtree 
   2  
 /  \
1    3


Input: 
       50
     /    \
  30       60
 /  \     /  \ 
5   20   45    70
              /  \
            65    80
Output: 5
The following subtree is the
maximum size BST subtree 
      60
     /  \ 
   45    70
        /  \
      65    80

Recomendado: Resuelva primero en » PRÁCTICA «, antes de pasar a la solución.

Hemos discutido dos métodos en la publicación a continuación. 
Encuentre el subárbol BST más grande en un árbol binario dado | Conjunto 1
En esta publicación, se analiza una solución O(n) diferente. Esta solución es más simple que las soluciones discutidas anteriormente y funciona en tiempo O(n).
La idea se basa en el método 3 de verificar si un árbol binario es un artículo BST
Un árbol es BST si lo siguiente es cierto para cada Node x. 
 

  1. El valor más grande en el subárbol izquierdo (de x) es más pequeño que el valor de x.
  2. El valor más pequeño en el subárbol derecho (de x) es mayor que el valor de x.

Atravieso un árbol de manera de abajo hacia arriba. Para cada Node atravesado, devolvemos valores máximos y mínimos en el subárbol enraizado con él. Si algún Node sigue las propiedades anteriores y el tamaño de 
 

C++14

// C++ program to find largest BST in a
// Binary Tree.
#include <bits/stdc++.h>
using namespace std;
 
/* A binary tree node has data,
pointer to left child and a
pointer to right child */
struct Node
{
    int data;
    struct Node* left;
    struct Node* right;
};
 
/* Helper function that allocates a new
node with the given data and NULL left
and right pointers. */
struct Node* newNode(int data)
{
    struct Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
 
    return(node);
}
 
// Information to be returned by every
// node in bottom up traversal.
struct Info
{
    int sz; // Size of subtree
    int max; // Min value in subtree
    int min; // Max value in subtree
    int ans; // Size of largest BST which
    // is subtree of current node
    bool isBST; // If subtree is BST
};
 
// Returns Information about subtree. The
// Information also includes size of largest
// subtree which is a BST.
Info largestBSTBT(Node* root)
{
    // Base cases : When tree is empty or it has
    // one child.
    if (root == NULL)
        return {0, INT_MIN, INT_MAX, 0, true};
    if (root->left == NULL && root->right == NULL)
        return {1, root->data, root->data, 1, true};
 
    // Recur for left subtree and right subtrees
    Info l = largestBSTBT(root->left);
    Info r = largestBSTBT(root->right);
 
    // Create a return variable and initialize its
    // size.
    Info ret;
    ret.sz = (1 + l.sz + r.sz);
 
    // If whole tree rooted under current root is
    // BST.
    if (l.isBST && r.isBST && l.max < root->data &&
            r.min > root->data)
    {
        ret.min = min(l.min, min(r.min, root->data));
        ret.max = max(r.max, max(l.max, root->data));
 
        // Update answer for tree rooted under
        // current 'root'
        ret.ans = max(l.ans, r.ans) + 1;
        ret.isBST = true;
 
        return ret;
    }
 
    // If whole tree is not BST, return maximum
    // of left and right subtrees
    ret.ans = max(l.ans, r.ans);
    ret.isBST = false;
 
    return ret;
}
 
/* Driver program to test above functions*/
int main()
{
    /* Let us construct the following Tree
        60
       /  \
      65  70
     /
    50 */
 
    struct Node *root = newNode(60);
    root->left = newNode(65);
    root->right = newNode(70);
    root->left->left = newNode(50);
    printf(" Size of the largest BST is %d\n",
           largestBSTBT(root).ans);
    return 0;
}
 
// This code is contributed by Vivek Garg in a
// comment on below set 1.
// www.geeksforgeeks.org/find-the-largest-subtree-in-a-tree-that-is-also-a-bst/
// This code is updated by Naman Sharma

Java

// Java program to find largest BST in a Binary Tree.
 
/* A binary tree node has data, pointer to left child and a
 * pointer to right child */
class Node {
    int data;
    Node left, right;
 
    public Node(final int d) { data = d; }
}
 
class GFG {
 
    public static void main(String[] args)
    {
 
        /* Let us construct the following Tree
         60
        /  \
       65  70
      /
     50 */
 
        final Node node1 = new Node(60);
        node1.left = new Node(65);
        node1.right = new Node(70);
        node1.left.left = new Node(50);
 
        System.out.print("Size of the largest BST is "
                         + Solution.largestBst(node1)
                         + "\n");
    }
}
 
class Solution {
    static int MAX = Integer.MAX_VALUE;
    static int MIN = Integer.MIN_VALUE;
 
    static class nodeInfo {
        int size; // Size of subtree
        int max; // Min value in subtree
        int min; // Max value in subtree
        boolean isBST; // If subtree is BST
 
        nodeInfo() {}
 
        nodeInfo(int size, int max, int min, boolean isBST)
        {
            this.size = size;
            this.max = max;
            this.min = min;
            this.isBST = isBST;
        }
    }
 
    static nodeInfo largestBST(Node root)
    {
 
        // Base case : When the current subtree is empty or
        // the node corresponds to a null.
        if (root == null) {
            return new nodeInfo(0, Integer.MIN_VALUE,
                                Integer.MAX_VALUE, true);
        }
        // We will here do the postorder traversal since we
        // want our left and right subtrees to be computed
        // first.
 
        // Recur for left subtree and right subtrees
        nodeInfo left = largestBST(root.left);
        nodeInfo right = largestBST(root.right);
 
        // Create a new nodeInfo variable to store info
        // about the current node.
        nodeInfo returnInfo = new nodeInfo();
 
        returnInfo.min = Math.min(
            Math.min(left.min, right.min), root.data);
        returnInfo.max = Math.max(
            Math.max(left.max, right.max), root.data);
        returnInfo.isBST = left.isBST && right.isBST
                           && root.data > left.max
                           && root.data < right.min;
 
        /*
        If suppose the left and right subtrees of the
        current node are BST and the current node value is
        greater than the maximum value in the left subtree
        and also the current node value is smaller that the
        minimum value in the right subtree (Basic conditions
        for the formation of BST) then our whole subtree
        with the root as current root can be consider as a
        BST. Hence the size of the BST will become size of
        left BST subtree + size of right BST subtree +
        1(adding current node).
 
        Else we will consider the largest of the left BST or
        the  right BST.
        */
        if (returnInfo.isBST)
            returnInfo.size = left.size + right.size + 1;
        else
            returnInfo.size
                = Math.max(left.size, right.size);
 
        return returnInfo;
    }
 
    // Return the size of the largest sub-tree which is also
    // a BST
    static int largestBst(Node root)
    {
        return largestBST(root).size;
    }
}
// This code is contributed by Andrei Sljusar
// This code is updated by Utkarsh Saxena.

Python3

# Python program to find largest
# BST in a Binary Tree.
 
INT_MIN = -2147483648
INT_MAX = 2147483647
 
# Helper function that allocates a new
# node with the given data and None left
# and right pointers.
class newNode:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Returns Information about subtree. The
# Information also includes size of largest
# subtree which is a BST
def largestBSTBT(root):
     
# Base cases : When tree is empty or it has
    # one child.
    if (root == None):
        return 0, INT_MIN, INT_MAX, 0, True
    if (root.left == None and root.right == None) :
        return 1, root.data, root.data, 1, True
 
    # Recur for left subtree and right subtrees
    l = largestBSTBT(root.left)
    r = largestBSTBT(root.right)
 
    # Create a return variable and initialize its
    # size.
    ret = [0, 0, 0, 0, 0]
    ret[0] = (1 + l[0] + r[0])
 
    # If whole tree rooted under current root is
    # BST.
    if (l[4] and r[4] and l[1] <
        root.data and r[2] > root.data) :
     
        ret[2] = min(l[2], min(r[2], root.data))
        ret[1] = max(r[1], max(l[1], root.data))
 
        # Update answer for tree rooted under
        # current 'root'
        ret[3] = max(l[3], r[3]) + 1;
        ret[4] = True
 
        return ret
     
 
    # If whole tree is not BST, return maximum
    # of left and right subtrees
    ret[3] = max(l[3], r[3])
    ret[4] = False
 
    return ret
 
# Driver Code
if __name__ == '__main__':
     
    """Let us construct the following Tree
        60
        / \
        65 70
    /
    50 """
    root = newNode(60)
    root.left = newNode(65)
    root.right = newNode(70)
    root.left.left = newNode(50)
    print("Size of the largest BST is",
                    largestBSTBT(root)[3])
                             
# This code is contributed
# Shubham Singh(SHUBHAMSINGH10)
# Naman Sharma (NAMANSHARMA1805)

C#

// C# program to find largest BST in a Binary Tree.
 
/* A binary tree node has data, pointer to left child and a
 * pointer to right child */
using System;
public
 
  class Node {
    public
 
      int data;
    public
 
      Node left,
    right;
 
    public Node(int d) { data = d; }
  }
 
public class GFG {
 
  public static void Main(String[] args)
  {
 
    /*
         * Let us construct the following Tree 60 / \ 65 70
         * / 50
         */
 
    Node node1 = new Node(60);
    node1.left = new Node(65);
    node1.right = new Node(70);
    node1.left.left = new Node(50);
 
    Console.Write("Size of the largest BST is "
                  + Solution.largestBst(node1) + "\n");
  }
}
 
public
 
  class Solution {
    static int MAX = int.MaxValue;
    static int MIN = int.MinValue;
 
    public
 
      class nodeInfo {
        public int size; // Size of subtree
        public int max; // Min value in subtree
        public int min; // Max value in subtree
        public bool isBST; // If subtree is BST
 
        public
 
          nodeInfo()
        {
        }
 
        public
 
          nodeInfo(int size, int max, int min, bool isBST)
        {
          this.size = size;
          this.max = max;
          this.min = min;
          this.isBST = isBST;
        }
      }
 
    public
 
      static nodeInfo
      largestBST(Node root)
    {
 
      // Base cases : When tree is empty or it has one
      // child.
      if (root == null) {
        return new nodeInfo(0, MIN, MAX, true);
      }
      if (root.left == null && root.right == null) {
        return new nodeInfo(1, root.data, root.data,
                            true);
      }
 
      // Recur for left subtree and right subtrees
      nodeInfo left = largestBST(root.left);
      nodeInfo right = largestBST(root.right);
 
      // Create a return variable and initialize its size.
      nodeInfo returnInfo = new nodeInfo();
 
      // If whole tree rooted under current root is BST.
      if (left.isBST && right.isBST
          && left.max < root.data
          && right.min > root.data) {
        returnInfo.min = Math.Min(
          Math.Min(left.min, right.min), root.data);
        returnInfo.max = Math.Max(
          Math.Max(left.max, right.max), root.data);
 
        // Update answer for tree rooted under current
        // 'root'
        returnInfo.size = Math.Max(left.size, right.size) + 1;
        returnInfo.isBST = true;
        return returnInfo;
      }
 
      // If whole tree is not BST, return maximum of left
      // and right subtrees
      returnInfo.size = Math.Max(left.size, right.size);
      returnInfo.isBST = false;
      return returnInfo;
    }
 
    // Return the size of the largest sub-tree which is also
    // a BST
    public
 
      static int
      largestBst(Node root)
    {
      return largestBST(root).size;
    }
  }
 
// This code is contributed by Rajput-Ji
//This code is updated by Naman Sharma

Javascript

<script>
// javascript program to find largest BST in a Binary Tree.
 
/* A binary tree node has data, pointer to left child and a pointer to right child */
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}
 
var MAX = Number.MAX_VALUE;
    var MIN = Number.MIN_VALUE;
 
     class nodeInfo {
 
        constructor(size , max , min,  isBST) {
            this.size = size;
            this.max = max;
            this.min = min;
            this.isBST = isBST;
        }
    }
 
     function largestBST(root) {
 
        // Base cases : When tree is empty or it has one child.
        if (root == null) {
            return new nodeInfo(0, MIN, MAX, true);
        }
        if (root.left == null && root.right == null) {
            return new nodeInfo(1, root.data, root.data, true);
        }
 
        // Recur for left subtree and right subtrees
        var left = largestBST(root.left);
        var right = largestBST(root.right);
 
        // Create a return variable and initialize its size.
        var returnInfo = new nodeInfo();
 
        // If whole tree rooted under current root is BST.
        if (left.isBST && right.isBST && left.max < root.data && right.min > root.data) {
            returnInfo.min = Math.min(Math.min(left.min, right.min), root.data);
            returnInfo.max = Math.max(Math.max(left.max, right.max), root.data);
 
            // Update answer for tree rooted under current 'root'
            returnInfo.size = math.max(left.size, right.size) + 1;
            returnInfo.isBST = true;
            return returnInfo;
        }
 
        // If whole tree is not BST, return maximum of left and right subtrees
        returnInfo.size = Math.max(left.size, right.size);
        returnInfo.isBST = false;
        return returnInfo;
    }
 
    // Return the size of the largest sub-tree which is also a BST
    function largestBst(root) {
        return largestBST(root).size;
}
 
        /*
         * Let us construct the following Tree
         60
        / \
       65 70
      /
      50
         */
 
        var node1 = new Node(60);
        node1.left = new Node(65);
        node1.right = new Node(70);
        node1.left.left = new Node(50);
 
        document.write("Size of the largest BST is " + largestBst(node1) + "\n");
 
// This code is contributed by Rajput-Ji and Naman Sharma
</script>
Producción

 Size of the largest BST is 2

Complejidad de tiempo : O(n)

Complejidad espacial : O (n) Para la pila de llamadas desde que se usa la recursividad

Este artículo es una contribución de Utkarsh Saxena . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *