Considere un árbol binario en el que cada Node tiene dos hijos excepto los Nodes hoja. Si un Node se etiqueta como ‘v’, sus hijos de la derecha se etiquetarán como 2v+1 y los hijos de la izquierda como 2v. La raíz está etiquetada como
Dados dos Nodes etiquetados como i y j, la tarea es encontrar la distancia más corta y el camino de i a j. E imprima la ruta del Node i y el Node j desde el Node raíz.
Ejemplos:
Entrada: i = 1, j = 2
Salida: 1
Explicación:
La ruta es 1 2Entrada: i = 4, j = 3
Salida: 3
Explicación:
La ruta es 4 2 1 3
Este problema es principalmente una extensión de Encontrar distancia entre dos claves dadas de un árbol binario . Aquí no sólo encontramos la distancia más corta sino también el camino.
La distancia entre los dos Nodes i y j será igual a dist(i, LCA(i, j)) + dist(j, LCA(i, j)) donde LCA significa el ancestro común más bajo de los Nodes etiquetados como i y j . Si un número x se representa en forma binaria, entonces 2*x se puede representar agregando 0 a la representación binaria de x y 2x+1 se puede representar agregando 1 a la representación binaria de x. Esto se debe a que cuando agregamos 0, todos los términos presentes en la forma binaria de x se desplazan a la izquierda, por lo que se duplica de manera similar cuando agregamos 1, obtenemos 2x+1. Supongamos que la representación binaria de un Node es 1010, esto nos dice la ruta de este Node desde la raíz. El primer término ‘1’ representa la raíz, el segundo término 0 representa el giro a la izquierda, luego el tercer término 1 representa un giro a la derecha desde el Node anterior y, finalmente, 0 representa el giro a la izquierda.
El Node 10 en forma binaria es 1010 y el 13 en forma binaria es 1101. En segundo lugar, la longitud de la representación binaria de cualquier Node también informa sobre su nivel en un árbol binario. Supongamos que la representación binaria de i tiene una longitud de m y es [Tex]i_2 [/Tex]… y la representación binaria del Node j tiene una longitud de n [Tex]j_2 [/Tex]…… .
Así conocemos el camino de i y j desde la raíz. Encuentre k tal que para todo p<=k = . Este es el LCA de i y j en forma binaria. Así que dist(i, LCA(i, j)) será m – k y dist(j, LCA(i, j)) = n – k. entonces la respuesta será m + n – 2k. E imprimir la ruta tampoco es un gran problema, simplemente almacene la ruta de i a LCA y la ruta de j a LCA y concatene.
C++
// C++ representation of finding shortest // distance between node i and j #include <bits/stdc++.h> using namespace std; // prints the path between node i and node j void ShortestPath(int i, int j, int k, int m, int n) { // path1 stores path of node i to lca and // path2 stores path of node j to lca vector<int> path1, path2; int x = m - 1; // push node i in path1 path1.push_back(i); // keep pushing parent of node labelled // as i to path1 until lca is reached while (x != k) { path1.push_back(i / 2); i = i / 2; x--; } int y = n - 1; // push node j to path2 path2.push_back(j); // keep pushing parent of node j till // lca is reached while (y != k) { path2.push_back(j / 2); j = j / 2; y--; } // printing path from node i to lca for (int l = 0; l < path1.size(); l++) cout << path1[l] << " "; // printing path from lca to node j for (int l = path2.size() - 2; l >= 0; l--) cout << path2[l] << " "; cout << endl; } // returns the shortest distance between // nodes labelled as i and j int ShortestDistance(int i, int j) { // vector to store binary form of i and j vector<int> v1, v2; // finding binary form of i and j int p1 = i; int p2 = j; while (i != 0) { v1.push_back(i % 2); i = i / 2; } while (j != 0) { v2.push_back(j % 2); j = j / 2; } // as binary form will be in reverse order // reverse the vectors reverse(v1.begin(), v1.end()); reverse(v2.begin(), v2.end()); // finding the k that is lca (i, j) int m = v1.size(), n = v2.size(), k = 0; if (m < n) { while (k < m && v1[k] == v2[k]) k++; } else { while (k < n && v1[k] == v2[k]) k++; } ShortestPath(p1, p2, k - 1, m, n); return m + n - 2 * k; } // Driver Code int main() { cout << ShortestDistance(1, 2) << endl; cout << ShortestDistance(4, 3) << endl; return 0; }
Java
// Java representation of finding shortest // distance between node i and j import java.util.*; class GFG { // prints the path between node i and node j static void ShortestPath(int i, int j, int k, int m, int n) { // path1 stores path of node i to lca and // path2 stores path of node j to lca Vector<Integer> path1=new Vector<Integer>(), path2=new Vector<Integer>(); int x = m - 1; // push node i in path1 path1.add(i); // keep pushing parent of node labelled // as i to path1 until lca is reached while (x != k) { path1.add(i / 2); i = i / 2; x--; } int y = n - 1; // push node j to path2 path2.add(j); // keep pushing parent of node j till // lca is reached while (y != k) { path2.add(j / 2); j = j / 2; y--; } // printing path from node i to lca for (int l = 0; l < path1.size(); l++) System.out.print( path1.get(l) + " "); // printing path from lca to node j for (int l = path2.size() - 2; l >= 0; l--) System.out.print( path2.get(l) + " "); System.out.println(); } // returns the shortest distance between // nodes labelled as i and j static int ShortestDistance(int i, int j) { // vector to store binary form of i and j Vector<Integer> v1=new Vector<Integer>(), v2=new Vector<Integer>(); // finding binary form of i and j int p1 = i; int p2 = j; while (i != 0) { v1.add(i % 2); i = i / 2; } while (j != 0) { v2.add(j % 2); j = j / 2; } // as binary form will be in reverse order // reverse the vectors Collections.reverse(v1); Collections.reverse(v2); // finding the k that is lca (i, j) int m = v1.size(), n = v2.size(), k = 0; if (m < n) { while (k < m && v1.get(k) == v2.get(k)) k++; } else { while (k < n && v1.get(k) == v2.get(k)) k++; } ShortestPath(p1, p2, k - 1, m, n); return m + n - 2 * k; } // Driver code public static void main(String args[]) { System.out.println( ShortestDistance(1, 2) ); System.out.println(ShortestDistance(4, 3) ); } } // This code is contributed by Arnab Kundu
Python3
# Python3 representation of finding # shortest distance between node i and j # Prints the path between node i and node j def ShortestPath(i, j, k, m, n): # path1 stores path of node i to lca and # path2 stores path of node j to lca path1, path2 = [], [] x = m - 1 # push node i in path1 path1.append(i) # keep pushing parent of node labelled # as i to path1 until lca is reached while x != k: path1.append(i // 2) i = i // 2 x -= 1 y = n - 1 # push node j to path2 path2.append(j) # keep pushing parent of node # j till lca is reached while y != k: path2.append(j / 2) j = j // 2 y -= 1 # printing path from node i to lca for l in range(0, len(path1)): print(path1[l], end=" ") # printing path from lca to node j for l in range(len(path2) - 2, -1, -1): print(path2[l], end=" ") print() # Returns the shortest distance # between nodes labelled as i and j def ShortestDistance(i, j): # vector to store binary form of i and j v1, v2 = [], [] # finding binary form of i and j p1, p2 = i, j while i != 0: v1.append(i % 2) i = i // 2 while j != 0: v2.append(j % 2) j = j // 2 # as binary form will be in reverse # order reverse the vectors v1 = v1[::-1] v2 = v2[::-1] # finding the k that is lca (i, j) m, n, k = len(v1), len(v2), 0 if m < n: while k < m and v1[k] == v2[k]: k += 1 else: while k < n and v1[k] == v2[k]: k += 1 ShortestPath(p1, p2, k - 1, m, n) return m + n - 2 * k # Driver Code if __name__ == "__main__": print(ShortestDistance(1, 2)) print(ShortestDistance(4, 3)) # This code is contributed by Rituraj Jain
C#
// C# representation of finding shortest // distance between node i and j using System; using System.Collections.Generic; class GFG { // prints the path between node i and node j static void ShortestPath(int i, int j, int k, int m, int n) { // path1 stores path of node i to lca and // path2 stores path of node j to lca List<int> path1=new List<int>(), path2=new List<int>(); int x = m - 1; // push node i in path1 path1.Add(i); // keep pushing parent of node labelled // as i to path1 until lca is reached while (x != k) { path1.Add(i / 2); i = i / 2; x--; } int y = n - 1; // push node j to path2 path2.Add(j); // keep pushing parent of node j till // lca is reached while (y != k) { path2.Add(j / 2); j = j / 2; y--; } // printing path from node i to lca for (int l = 0; l < path1.Count; l++) Console.Write( path1[l] + " "); // printing path from lca to node j for (int l = path2.Count - 2; l >= 0; l--) Console.Write( path2[l] + " "); Console.WriteLine(); } // returns the shortest distance between // nodes labelled as i and j static int ShortestDistance(int i, int j) { // vector to store binary form of i and j List<int> v1=new List<int>(), v2=new List<int>(); // finding binary form of i and j int p1 = i; int p2 = j; while (i != 0) { v1.Add(i % 2); i = i / 2; } while (j != 0) { v2.Add(j % 2); j = j / 2; } // as binary form will be in reverse order // reverse the vectors v1.Reverse(); v2.Reverse(); // finding the k that is lca (i, j) int m =v1.Count, n =v2.Count, k = 0; if (m < n) { while (k < m && v1[k] == v2[k]) k++; } else { while (k < n && v1[k] == v2[k]) k++; } ShortestPath(p1, p2, k - 1, m, n); return m + n - 2 * k; } // Driver code public static void Main(String []args) { Console.WriteLine( ShortestDistance(1, 2) ); Console.WriteLine(ShortestDistance(4, 3) ); } } // This code is contributed by Princi Singh
Javascript
<script> // Javascript representation of finding shortest // distance between node i and j // prints the path between node i and node j function ShortestPath(i,j,k,m,n) { // path1 stores path of node i to lca and // path2 stores path of node j to lca let path1=[]; let path2=[]; let x = m - 1; // push node i in path1 path1.push(i); // keep pushing parent of node labelled // as i to path1 until lca is reached while (x != k) { path1.push(Math.floor(i / 2)); i = Math.floor(i / 2); x--; } let y = n - 1; // push node j to path2 path2.push(j); // keep pushing parent of node j till // lca is reached while (y != k) { path2.push(Math.floor(j / 2)); j = Math.floor(j / 2); y--; } // printing path from node i to lca for (let l = 0; l < path1.length; l++) document.write( path1[l] + " "); // printing path from lca to node j for (let l = path2.length - 2; l >= 0; l--) document.write( path2[l] + " "); document.write("<br>"); } // returns the shortest distance between // nodes labelled as i and j function ShortestDistance(i,j) { // vector to store binary form of i and j let v1=[]; let v2=[]; // finding binary form of i and j let p1 = i; let p2 = j; while (i != 0) { v1.push(i % 2); i = Math.floor(i / 2); } while (j != 0) { v2.push(j % 2); j = Math.floor(j / 2); } // as binary form will be in reverse order // reverse the vectors v1.reverse(); v2.reverse(); // finding the k that is lca (i, j) let m =v1.length, n =v2.length, k = 0; if (m < n) { while (k < m && v1[k] == v2[k]) k++; } else { while (k < n && v1[k] == v2[k]) k++; } ShortestPath(p1, p2, k - 1, m, n); return m + n - 2 * k; } // Driver code document.write( ShortestDistance(1, 2) +"<br>"); document.write(ShortestDistance(4, 3) +"<br>"); // This code is contributed by avanitrachhadiya2155 </script>
Producción:
1 2 1 4 2 1 3 3
Análisis de Complejidad:
Complejidad de Tiempo: O(i + j) ya que estamos cambiando el valor de i y j a la derecha para cada recorrido
Espacio auxiliar: O(log_2 i + log_2 j) ya que estamos almacenando rutas para cada valor de desplazamiento a la derecha de i y j .
Este artículo es una contribución de Ayush Jha . 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