Количество пар с заданной суммой в дереве двоичного поиска
Учитывая дерево двоичного поиска и число X. Задача состоит в том, чтобы найти количество различных пар различных узлов в BST с суммой, равной X. Нет двух узлов с одинаковыми значениями.
Примеры:
Ввод: X = 5 5 / 3 7 / / 2 4 6 8 Выход: 1 {2, 3} - единственная возможная пара. Таким образом, ответ равен 1. Ввод: X = 6 1 2 3 4 5 Выход: 2 Возможные пары: {{1, 5}, {2, 4}}.
Рекомендуется: сначала попробуйте свой подход в {IDE}, прежде чем переходить к решению.
Наивный подход : идея состоит в том, чтобы хешировать все элементы BST или преобразовать BST в отсортированный массив. После этого найдите количество пар, используя приведенный здесь алгоритм.
Сложность времени: O (N).
Космическая сложность: O (N).
Подход, оптимизированный по пространству: идея состоит в том, чтобы использовать технику двух указателей на BST. Поддерживайте итераторы прямого и обратного направления, которые будут выполнять итерацию BST в порядке обхода по порядку и в обратном порядке соответственно.
- Создайте итераторы прямого и обратного направления для BST. Предположим, что значения узлов, на которые они указывают, равны v 1 и v 2 соответственно.
- Теперь на каждом шагу
- Если v 1 + v 2 = X, пара найдена, таким образом увеличьте счет на 1.
- Если v 1 + v 2 меньше или равно x, мы сделаем прямой итератор точкой на следующий элемент.
- Если v 1 + v 2 больше x, мы заставим итератор в обратном направлении указывать на предыдущий элемент.
- Повторите вышеуказанные шаги, пока оба итератора не укажут на один и тот же узел.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Node of Binary tree struct node { int data; node* left; node* right; node( int data) { this ->data = data; left = NULL; right = NULL; } }; // Function to find a pair int cntPairs(node* root, int x) { // Stack to store nodes for // forward and backward iterator stack<node *> it1, it2; // Initializing forward iterator node* c = root; while (c != NULL) it1.push(c), c = c->left; // Initializing backward iterator c = root; while (c != NULL) it2.push(c), c = c->right; // Variable to store final answer int ans = 0; // two pointer technique while (it1.top() != it2.top()) { // Variables to store the // value of the nodes current // iterators are pointing to. int v1 = it1.top()->data; int v2 = it2.top()->data; // If we find a pair // then count is increased by 1 if (v1 + v2 == x) ans++; // Moving forward iterator if (v1 + v2 <= x) { c = it1.top()->right; it1.pop(); while (c != NULL) it1.push(c), c = c->left; } // Moving backward iterator else { c = it2.top()->left; it2.pop(); while (c != NULL) it2.push(c), c = c->right; } } // Returning final answer return ans; } // Driver code int main() { /* 5 / 3 7 / / 2 4 6 8 */ node* root = new node(5); root->left = new node(3); root->right = new node(7); root->left->left = new node(2); root->left->right = new node(4); root->right->left = new node(6); root->right->right = new node(8); int x = 10; cout << cntPairs(root, x); return 0; } |
Java
// Java implementation of the approach import java.util.*; class GFG { // Node of Binary tree static class node { int data; node left; node right; node( int data) { this .data = data; left = null ; right = null ; } }; // Function to find a pair static int cntPairs(node root, int x) { // Stack to store nodes for // forward and backward iterator Stack<node > it1 = new Stack<>(); Stack<node > it2 = new Stack<>(); // Initializing forward iterator node c = root; while (c != null ) { it1.push(c); c = c.left; } // Initializing backward iterator c = root; while (c != null ) { it2.push(c); c = c.right; } // Variable to store final answer int ans = 0 ; // two pointer technique while (it1.peek() != it2.peek()) { // Variables to store the // value of the nodes current // iterators are pointing to. int v1 = it1.peek().data; int v2 = it2.peek().data; // If we find a pair // then count is increased by 1 if (v1 + v2 == x) ans++; // Moving forward iterator if (v1 + v2 <= x) { c = it1.peek().right; it1.pop(); while (c != null ) { it1.push(c); c = c.left; } } // Moving backward iterator else { c = it2.peek().left; it2.pop(); while (c != null ) { it2.push(c); c = c.right; } } } // Returning final answer return ans; } // Driver code public static void main(String[] args) { /* 5 / 3 7 / / 2 4 6 8 */ node root = new node( 5 ); root.left = new node( 3 ); root.right = new node( 7 ); root.left.left = new node( 2 ); root.left.right = new node( 4 ); root.right.left = new node( 6 ); root.right.right = new node( 8 ); int x = 10 ; System.out.print(cntPairs(root, x)); } } // This code is contributed by Rajput-Ji |
Python
# Python implementation of above algorithm # Utility class to create a node class node: def __init__( self , key): self .data = key self .left = self .right = None # Function to find a pair def cntPairs( root, x): # Stack to store nodes for # forward and backward iterator it1 = [] it2 = [] # Initializing forward iterator c = root while (c ! = None ): it1.append(c) c = c.left # Initializing backward iterator c = root while (c ! = None ): it2.append(c) c = c.right # Variable to store final answer ans = 0 # two pointer technique while (it1[ - 1 ] ! = it2[ - 1 ]) : # Variables to store the # value of the nodes current # iterators are pointing to. v1 = it1[ - 1 ].data v2 = it2[ - 1 ].data # If we find a pair # then count is increased by 1 if (v1 + v2 = = x): ans = ans + 1 # Moving forward iterator if (v1 + v2 < = x) : c = it1[ - 1 ].right it1.pop() while (c ! = None ): it1.append(c) c = c.left # Moving backward iterator else : c = it2[ - 1 ].left it2.pop() while (c ! = None ): it2.append(c) c = c.right # Returning final answer return ans # Driver code # 5 # / # 3 7 # / / # 2 4 6 8 root = node( 5 ) root.left = node( 3 ) root.right = node( 7 ) root.left.left = node( 2 ) root.left.right = node( 4 ) root.right.left = node( 6 ) root.right.right = node( 8 ) x = 10 print (cntPairs(root, x)) # This code is contributed by Arnab Kundu |
C#
// C# implementation of the approach using System; using System.Collections.Generic; class GFG { // Node of Binary tree public class node { public int data; public node left; public node right; public node( int data) { this .data = data; left = null ; right = null ; } }; // Function to find a pair static int cntPairs(node root, int x) { // Stack to store nodes for // forward and backward iterator Stack<node > it1 = new Stack<node>(); Stack<node > it2 = new Stack<node>(); // Initializing forward iterator node c = root; while (c != null ) { it1.Push(c); c = c.left; } // Initializing backward iterator c = root; while (c != null ) { it2.Push(c); c = c.right; } // Variable to store readonly answer int ans = 0; // two pointer technique while (it1.Peek() != it2.Peek()) { // Variables to store the // value of the nodes current // iterators are pointing to. int v1 = it1.Peek().data; int v2 = it2.Peek().data; // If we find a pair // then count is increased by 1 if (v1 + v2 == x) ans++; // Moving forward iterator if (v1 + v2 <= x) { c = it1.Peek().right; it1.Pop(); while (c != null ) { it1.Push(c); c = c.left; } } // Moving backward iterator else { c = it2.Peek().left; РЕКОМЕНДУЕМЫЕ СТАТЬИ |