Recuento de rutas estrictamente crecientes y decrecientes en árbol binario dirigido

Dado un árbol binario dirigido de N Nodes cuyas aristas van del padre al hijo , la tarea es contar el número de caminos estrictamente crecientes y decrecientes.

Nota: un camino comienza en la raíz y termina en cualquier hoja.

Ejemplos:

Entrada: N = 6
árbol = 6
                 / \
              4 7
               \ / \
                5 6 8
Salida: 10 8
Explicación: Para el árbol binario anterior, los caminos estrictamente crecientes son:
    Todos los caminos que consisten en un solo Node son = 6.
    Los caminos que contienen dos Nodes son: 4->5, 7->8, 6->7 = 3. 
    Los caminos que contienen tres Nodes son: 6->7->8 = 1. 
    Por lo tanto, el número de caminos estrictamente crecientes es 6 + 3 + 1 = 10 .
Para el árbol binario anterior, los caminos estrictamente decrecientes son:
    Todos los caminos que consisten en un solo Node son = 6.
    Los caminos que contienen dos Nodes son: 6->4, 7->6 = 2.
    Por lo tanto, la cuenta de caminos estrictamente decrecientes es 6 + 2 = 8 .

Entrada: N = 5
árbol 15
                     /         
                   8            
                    \
                     2
                  / \
               13 9
Salida: 7 8
Explicación: 
Para el árbol binario anterior, los caminos estrictamente crecientes son:
    Todos los caminos que consisten en un solo Node son = 5.
    Los caminos que contienen dos Nodes son: 2->9, 2->13 = 2.
    Por lo tanto, la cuenta de caminos estrictamente crecientes es 5 + 2 = 7 .
Para el árbol binario anterior, los caminos estrictamente decrecientes son:
    Todos los caminos que consisten en un solo Node son = 5.
    Los caminos que contienen dos Nodes son: 15->8, 8->2 = 2.
    Los caminos que contienen tres Nodes son: 15->8->2 = 1.
    Por lo tanto, la cuenta de caminos estrictamente decrecientes es 5 + 2 + 1 = 8 .

 

Planteamiento: El problema se puede resolver con base en la siguiente observación:

Si un camino que comienza desde cualquier Node u es estrictamente creciente y su valor es mayor que el valor de su padre (por ejemplo , v ), entonces todos los caminos estrictamente crecientes que comienzan desde u también son estrictamente crecientes cuando el Node inicial es v . Lo mismo es cierto en el caso de trayectorias estrictamente decrecientes.

A partir de la observación anterior, el problema se puede resolver con la ayuda de la recursividad . Siga los pasos a continuación para resolver el problema:

  • Use una función recursiva para atravesar el árbol comenzando desde la raíz y para cada Node devuelva el recuento de rutas estrictamente crecientes y estrictamente decrecientes desde ese Node.
  • En cada recursión:
    • Compruebe si la ruta desde el Node actual hasta un hijo (izquierda o derecha) aumenta o disminuye.
    • Llame a la función recursiva para el niño .
    • Agregue el conteo de rutas crecientes o decrecientes al conteo total si la ruta desde el Node actual hasta el hijo es creciente o decreciente respectivamente.
  • Devuelve el conteo final de camino creciente o decreciente obtenido para root.

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Following is the TreeNode
// class structure:
template <typename T>
class TreeNode {
public:
    T data;
    TreeNode<T>* left;
    TreeNode<T>* right;
 
    TreeNode(T data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
 
// Helper function to get the answer
pair<int, int> countPathsHelper(TreeNode<int>* root,
                                int& increase,
                                int& decrease)
{
    // If the root is NULL,
    // then no strictly increasing or
    // decreasing path.
    if (root == NULL) {
        return { 0, 0 };
    }
 
    // Call the function for both
    // the left and right child.
    pair<int, int> p1
        = countPathsHelper(root->left,
                           increase, decrease);
    pair<int, int> p2
        = countPathsHelper(root->right,
                           increase, decrease);
 
    // Initialize 'inc' and 'dec' to 1
    int inc = 1, dec = 1;
 
    // If the left child is not NULL.
    if (root->left != NULL) {
 
        // Check if the value is
        // increasing from parent to child.
        if (root->data < root->left->data) {
 
            // Add the count of strictly
            // increasing paths of
            // child to parent.
            inc += p1.first;
        }
 
        // Check if the value is decreasing
        // from parent to child.
        if (root->data > root->left->data) {
 
            // Add the count of strictly
            // decreasing paths of
            // child to parent.
            dec += p1.second;
        }
    }
    if (root->right != NULL) {
 
        // Check if the value is
        // increasing from parent to child.
        if (root->data < root->right->data) {
 
            // Add the count of strictly
            // increasing paths of
            // child to parent.
            inc += p2.first;
        }
 
        // Check if the value is
        // decreasing from parent to child
        if (root->data > root->right->data) {
 
            // Add the count of strictly
            // decreasing paths of
            // child to parent.
            dec += p2.second;
        }
    }
 
    // Add the total count of
    // strictly increasing paths to
    // the global strictly increasing
    // paths counter.
    increase += inc;
 
    // Add the total count of
    // strictly decreasing paths to
    // the global strictly
    // decreasing paths counter.
    decrease += dec;
    return { inc, dec };
}
 
// Function to count the paths
pair<int, int> countPaths(TreeNode<int>* root)
{
    // 'increase' stores the
    // total strictly increasing paths.
    int increase = 0;
 
    // 'decrease' stores the
    // total strictly decreasing paths.
    int decrease = 0;
 
    countPathsHelper(root, increase, decrease);
    return { increase, decrease };
}
 
// Driver code
int main()
{
    int N = 6;
    TreeNode<int>* root
        = new TreeNode<int>(N);
    root->left = new TreeNode<int>(4);
    root->right = new TreeNode<int>(7);
    root->left->right = new TreeNode<int>(5);
    root->right->left = new TreeNode<int>(6);
    root->right->right = new TreeNode<int>(8);
 
    // Function call
    pair<int, int> ans = countPaths(root);
    cout << ans.first << " " << ans.second;
    return 0;
}

Java

// Java code for the above approach:
import java.util.*;
 
public class Main {
  static class Node {
    int data;
    Node left;
    Node right;
 
    Node(int data_value)
    {
      data = data_value;
      this.left = null;
      this.right = null;
    }
  }
  // 'increase' stores the
  // total strictly increasing paths.
  static int increase;
 
  // 'decrease' stores the
  // total strictly decreasing paths.
  static int decrease;
  // Helper function to get the answer
  static int[] countPathsHelper(Node root)
  {
    // If the root is NULL,
    // then no strictly increasing or
    // decreasing path.
    if (root == null) {
      int[] zero = {0,0};
      return zero;
    }
 
    // Call the function for both
    // the left and right child.
    int[] p1
      = countPathsHelper(root.left);
    int[] p2
      = countPathsHelper(root.right);
 
    // Initialize 'inc' and 'dec' to 1
    int inc = 1, dec = 1;
 
    // If the left child is not NULL.
    if (root.left != null) {
 
      // Check if the value is
      // increasing from parent to child.
      if (root.data < root.left.data) {
 
        // Add the count of strictly
        // increasing paths of
        // child to parent.
        inc += p1[0];
      }
 
      // Check if the value is decreasing
      // from parent to child.
      if (root.data > root.left.data) {
 
        // Add the count of strictly
        // decreasing paths of
        // child to parent.
        dec += p1[1];
      }
    }
    if (root.right != null) {
 
      // Check if the value is
      // increasing from parent to child.
      if (root.data < root.right.data) {
 
        // Add the count of strictly
        // increasing paths of
        // child to parent.
        inc += p2[0];
      }
 
      // Check if the value is
      // decreasing from parent to child
      if (root.data > root.right.data) {
 
        // Add the count of strictly
        // decreasing paths of
        // child to parent.
        dec += p2[1];
      }
    }
 
    // Add the total count of
    // strictly increasing paths to
    // the global strictly increasing
    // paths counter.
    increase += inc;
 
    // Add the total count of
    // strictly decreasing paths to
    // the global strictly
    // decreasing paths counter.
    decrease += dec;
    int[] ans = {inc,dec};
    return ans;
  }
 
  // Function to count the paths
  static int[] countPaths(Node root)
  {
    increase=0;
    decrease=0;
    countPathsHelper(root);
    int[] ans = {increase,decrease};
 
    return ans;
  }
 
  public static void main(String args[]) {
    int N = 6;
    Node root = new Node(N);
    root.left = new Node(4);
    root.right = new Node(7);
    root.left.right = new Node(5);
    root.right.left = new Node(6);
    root.right.right = new Node(8);
 
    // Function call
    int[] ans = countPaths(root);
    System.out.println(ans[0] + " " + ans[1]);
  }
}
 
// This code has been contributed by Sachin Sahara (sachin801)

Python3

# Python code for the above approach
 
## structure for a node
class Node:
    def __init__(self, d):
        self.data = d
        self.left = None
        self.right = None
 
## 'increase' stores the
## total strictly increasing paths.
increase = 0
 
## 'decrease' stores the
## total strictly decreasing paths.
decrease = 0
 
## Helper function to get the answer
def countPathsHelper(root):
 
    global increase
    global decrease
     
    ## If the root is NULL,
    ## then no strictly increasing or
    ## decreasing path.
    if (root == None):
        zero = [0, 0]
        return zero
 
    ## Call the function for both
    ## the left and right child.
    p1 = countPathsHelper(root.left)
    p2 = countPathsHelper(root.right)
 
    ## Initialize 'inc' and 'dec' to 1
    inc = 1
    dec = 1
 
    ## If the left child is not NULL.
    if (root.left != None):
 
        ## Check if the value is
        ## increasing from parent to child.
        if (root.data < root.left.data):
 
            ## Add the count of strictly
            ## increasing paths of
            ## child to parent.
            inc += p1[0];
 
        ## Check if the value is decreasing
        ## from parent to child.
        if (root.data > root.left.data):
 
            ## Add the count of strictly
            ## decreasing paths of
            ## child to parent.
            dec += p1[1]
 
    if (root.right != None):
 
        ## Check if the value is
        ## increasing from parent to child.
        if (root.data < root.right.data):
 
            ## Add the count of strictly
            ## increasing paths of
            ## child to parent.
            inc += p2[0]
 
            ## Check if the value is
            ## decreasing from parent to child
            if (root.data > root.right.data):
 
                ## Add the count of strictly
                ## decreasing paths of
                ## child to parent.
                dec += p2[1]
 
    ## Add the total count of
    ## strictly increasing paths to
    ## the global strictly increasing
    ## paths counter.
    increase += inc
 
    ## Add the total count of
    ## strictly decreasing paths to
    ## the global strictly
    ## decreasing paths counter.
    decrease += dec
    ans = [inc, dec]
    return ans
 
## Function to count the paths
def countPaths(root):
    global increase
    global decrease
 
    increase = 0
    decrease = 0
 
    countPathsHelper(root)
    ans = [increase, decrease]
 
    return ans
 
# Driver Code
if __name__=='__main__':
 
    N = 6
    root = Node(N)
    root.left = Node(4)
    root.right = Node(7)
    root.left.right = Node(5)
    root.right.left = Node(6)
    root.right.right = Node(8)
 
    ## Function call
    ans = countPaths(root)
    print(ans[0], ans[1])
 
    # This code is contributed by entertain2022.

C#

// C# program to count the number of
// strictly increasing and decreasing paths
using System;
 
public class GFG{
     
    public class Node {
        public int data;
        public Node left;
        public Node right;
      
        public Node(int data_value)
        {
          data = data_value;
          this.left = null;
          this.right = null;
        }
    }
     
      // 'increase' stores the
      // total strictly increasing paths.
      static int increase;
      
      // 'decrease' stores the
      // total strictly decreasing paths.
      static int decrease;
       
    // Helper function to get the answer
  static int[] countPathsHelper(Node root)
  {
        // If the root is NULL,
        // then no strictly increasing or
        // decreasing path.
        if (root == null) {
          int[] zero = {0,0};
          return zero;
        }
      
        // Call the function for both
        // the left and right child.
        int[] p1 = countPathsHelper(root.left);
        int[] p2 = countPathsHelper(root.right);
      
        // Initialize 'inc' and 'dec' to 1
        int inc = 1, dec = 1;
      
        // If the left child is not NULL.
        if (root.left != null) {
      
          // Check if the value is
          // increasing from parent to child.
          if (root.data < root.left.data) {
      
            // Add the count of strictly
            // increasing paths of
            // child to parent.
            inc += p1[0];
          }
      
          // Check if the value is decreasing
          // from parent to child.
          if (root.data > root.left.data) {
      
            // Add the count of strictly
            // decreasing paths of
            // child to parent.
            dec += p1[1];
          }
        }
        if (root.right != null) {
      
          // Check if the value is
          // increasing from parent to child.
          if (root.data < root.right.data) {
      
            // Add the count of strictly
            // increasing paths of
            // child to parent.
            inc += p2[0];
          }
      
          // Check if the value is
          // decreasing from parent to child
          if (root.data > root.right.data) {
      
            // Add the count of strictly
            // decreasing paths of
            // child to parent.
            dec += p2[1];
          }
        }
      
        // Add the total count of
        // strictly increasing paths to
        // the global strictly increasing
        // paths counter.
        increase += inc;
      
        // Add the total count of
        // strictly decreasing paths to
        // the global strictly
        // decreasing paths counter.
        decrease += dec;
        int[] ans = {inc,dec};
        return ans;
    }
     
      // Function to count the paths
      static int[] countPaths(Node root)
      {
        increase=0;
        decrease=0;
        countPathsHelper(root);
        int[] ans = {increase,decrease};
      
        return ans;
      }
     
    static public void Main (){
        //Code
        int N = 6;
        Node root = new Node(N);
        root.left = new Node(4);
        root.right = new Node(7);
        root.left.right = new Node(5);
        root.right.left = new Node(6);
        root.right.right = new Node(8);
      
        // Function call
        int[] ans = countPaths(root);
        Console.Write(ans[0] + " " + ans[1]);
    }
}
 
// This code is contributed by shruti456rawal
Producción

10 8

Complejidad temporal: O(N)
Espacio auxiliar: O(N)

Publicación traducida automáticamente

Artículo escrito por rohit768 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 *