给定平衡二进制搜索树(BST),编写一个函数isTripletPresent(),如果给定BST中存在一个三元组且总和等于0,则该函数返回true,否则返回false。预期的时间复杂度为O(n ^ 2),并且只能使用O(Logn)多余的空间。您可以修改给定的二进制搜索树。请注意,平衡BST的高度始终为O(Logn)
例如,对于后面的BST,isTripletPresent()应该返回true,因为存在一个三元组,其总和为0,该三元组为{-13,6,7}。
蛮力解决方案是考虑BST中的每个三元组,并检查总和是否加到零。该解决方案的时间复杂度将为O(n ^ 3)。
更好的解决方案是创建一个辅助数组,并在该数组中存储BST的有序遍历。数组将被排序,因为BST的顺序遍历始终会产生排序的数据。一旦有了Inorder遍历,就可以使用本文的方法2来查找和等于0的三元组。此解决方案在O(n ^ 2)时间内有效,但需要O(n)辅助空间。
以下是在O(n ^ 2)时间内有效并且使用O(Logn)额外空间的解决方案:
1)将给定的BST转换为双链表(DLL)
2)现在遍历DLL的每个节点,如果节点的密钥为负,则在DLL中找到一个对,其对等于当前节点的密钥乘以-1。为了找到这对,我们可以使用本文方法1中hasArrayTwoCandidates()中使用的方法。
C++
// A C++ program to check if there
// is a triplet with sum equal to 0 in
// a given BST
#include
using namespace std;
// A BST node has key, and left and right pointers
class node
{
public:
int key;
node *left;
node *right;
};
// A function to convert given BST to Doubly
// Linked List. left pointer is used
// as previous pointer and right pointer
// is used as next pointer. The function
// sets *head to point to first and *tail
// to point to last node of converted DLL
void convertBSTtoDLL(node* root, node** head, node** tail)
{
// Base case
if (root == NULL)
return;
// First convert the left subtree
if (root->left)
convertBSTtoDLL(root->left, head, tail);
// Then change left of current root
// as last node of left subtree
root->left = *tail;
// If tail is not NULL, then set right
// of tail as root, else current
// node is head
if (*tail)
(*tail)->right = root;
else
*head = root;
// Update tail
*tail = root;
// Finally, convert right subtree
if (root->right)
convertBSTtoDLL(root->right, head, tail);
}
// This function returns true if there
// is pair in DLL with sum equal to given
// sum. The algorithm is similar to hasArrayTwoCandidates()
// in method 1 of http://tinyurl.com/dy6palr
bool isPresentInDLL(node* head, node* tail, int sum)
{
while (head != tail)
{
int curr = head->key + tail->key;
if (curr == sum)
return true;
else if (curr > sum)
tail = tail->left;
else
head = head->right;
}
return false;
}
// The main function that returns
// true if there is a 0 sum triplet in
// BST otherwise returns false
bool isTripletPresent(node *root)
{
// Check if the given BST is empty
if (root == NULL)
return false;
// Convert given BST to doubly linked list. head and tail store the
// pointers to first and last nodes in DLLL
node* head = NULL;
node* tail = NULL;
convertBSTtoDLL(root, &head, &tail);
// Now iterate through every node and
// find if there is a pair with sum
// equal to -1 * heaf->key where head is current node
while ((head->right != tail) && (head->key < 0))
{
// If there is a pair with sum
// equal to -1*head->key, then return
// true else move forward
if (isPresentInDLL(head->right, tail, -1*head->key))
return true;
else
head = head->right;
}
// If we reach here, then
// there was no 0 sum triplet
return false;
}
// A utility function to create
// a new BST node with key as given num
node* newNode(int num)
{
node* temp = new node();
temp->key = num;
temp->left = temp->right = NULL;
return temp;
}
// A utility function to insert a given key to BST
node* insert(node* root, int key)
{
if (root == NULL)
return newNode(key);
if (root->key > key)
root->left = insert(root->left, key);
else
root->right = insert(root->right, key);
return root;
}
// Driver code
int main()
{
node* root = NULL;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
if (isTripletPresent(root))
cout << "Present";
else
cout << "Not Present";
return 0;
}
// This code is contributed by rathbhupendra
C
// A C program to check if there is a triplet with sum equal to 0 in
// a given BST
#include
// A BST node has key, and left and right pointers
struct node
{
int key;
struct node *left;
struct node *right;
};
// A function to convert given BST to Doubly Linked List. left pointer is used
// as previous pointer and right pointer is used as next pointer. The function
// sets *head to point to first and *tail to point to last node of converted DLL
void convertBSTtoDLL(node* root, node** head, node** tail)
{
// Base case
if (root == NULL)
return;
// First convert the left subtree
if (root->left)
convertBSTtoDLL(root->left, head, tail);
// Then change left of current root as last node of left subtree
root->left = *tail;
// If tail is not NULL, then set right of tail as root, else current
// node is head
if (*tail)
(*tail)->right = root;
else
*head = root;
// Update tail
*tail = root;
// Finally, convert right subtree
if (root->right)
convertBSTtoDLL(root->right, head, tail);
}
// This function returns true if there is pair in DLL with sum equal
// to given sum. The algorithm is similar to hasArrayTwoCandidates()
// in method 1 of http://tinyurl.com/dy6palr
bool isPresentInDLL(node* head, node* tail, int sum)
{
while (head != tail)
{
int curr = head->key + tail->key;
if (curr == sum)
return true;
else if (curr > sum)
tail = tail->left;
else
head = head->right;
}
return false;
}
// The main function that returns true if there is a 0 sum triplet in
// BST otherwise returns false
bool isTripletPresent(node *root)
{
// Check if the given BST is empty
if (root == NULL)
return false;
// Convert given BST to doubly linked list. head and tail store the
// pointers to first and last nodes in DLLL
node* head = NULL;
node* tail = NULL;
convertBSTtoDLL(root, &head, &tail);
// Now iterate through every node and find if there is a pair with sum
// equal to -1 * heaf->key where head is current node
while ((head->right != tail) && (head->key < 0))
{
// If there is a pair with sum equal to -1*head->key, then return
// true else move forward
if (isPresentInDLL(head->right, tail, -1*head->key))
return true;
else
head = head->right;
}
// If we reach here, then there was no 0 sum triplet
return false;
}
// A utility function to create a new BST node with key as given num
node* newNode(int num)
{
node* temp = new node;
temp->key = num;
temp->left = temp->right = NULL;
return temp;
}
// A utility function to insert a given key to BST
node* insert(node* root, int key)
{
if (root == NULL)
return newNode(key);
if (root->key > key)
root->left = insert(root->left, key);
else
root->right = insert(root->right, key);
return root;
}
// Driver program to test above functions
int main()
{
node* root = NULL;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
if (isTripletPresent(root))
printf("Present");
else
printf("Not Present");
return 0;
}
Java
// A Java program to check if there
// is a triplet with sum equal to 0 in
// a given BST
import java.util.*;
class GFG
{
// A BST node has key, and left and right pointers
static class node
{
int key;
node left;
node right;
};
static node head;
static node tail;
// A function to convert given BST to Doubly
// Linked List. left pointer is used
// as previous pointer and right pointer
// is used as next pointer. The function
// sets *head to point to first and *tail
// to point to last node of converted DLL
static void convertBSTtoDLL(node root)
{
// Base case
if (root == null)
return;
// First convert the left subtree
if (root.left != null)
convertBSTtoDLL(root.left);
// Then change left of current root
// as last node of left subtree
root.left = tail;
// If tail is not null, then set right
// of tail as root, else current
// node is head
if (tail != null)
(tail).right = root;
else
head = root;
// Update tail
tail = root;
// Finally, convert right subtree
if (root.right != null)
convertBSTtoDLL(root.right);
}
// This function returns true if there
// is pair in DLL with sum equal to given
// sum. The algorithm is similar to hasArrayTwoCandidates()
// in method 1 of http://tinyurl.com/dy6palr
static boolean isPresentInDLL(node head, node tail, int sum)
{
while (head != tail)
{
int curr = head.key + tail.key;
if (curr == sum)
return true;
else if (curr > sum)
tail = tail.left;
else
head = head.right;
}
return false;
}
// The main function that returns
// true if there is a 0 sum triplet in
// BST otherwise returns false
static boolean isTripletPresent(node root)
{
// Check if the given BST is empty
if (root == null)
return false;
// Convert given BST to doubly linked list. head and tail store the
// pointers to first and last nodes in DLLL
head = null;
tail = null;
convertBSTtoDLL(root);
// Now iterate through every node and
// find if there is a pair with sum
// equal to -1 * heaf.key where head is current node
while ((head.right != tail) && (head.key < 0))
{
// If there is a pair with sum
// equal to -1*head.key, then return
// true else move forward
if (isPresentInDLL(head.right, tail, -1*head.key))
return true;
else
head = head.right;
}
// If we reach here, then
// there was no 0 sum triplet
return false;
}
// A utility function to create
// a new BST node with key as given num
static node newNode(int num)
{
node temp = new node();
temp.key = num;
temp.left = temp.right = null;
return temp;
}
// A utility function to insert a given key to BST
static node insert(node root, int key)
{
if (root == null)
return newNode(key);
if (root.key > key)
root.left = insert(root.left, key);
else
root.right = insert(root.right, key);
return root;
}
// Driver code
public static void main(String[] args)
{
node root = null;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
if (isTripletPresent(root))
System.out.print("Present");
else
System.out.print("Not Present");
}
}
// This code is contributed by aashish1995
C#
// A C# program to check if there
// is a triplet with sum equal to 0 in
// a given BST
using System;
public class GFG
{
// A BST node has key, and left and right pointers
public class node
{
public int key;
public node left;
public node right;
};
static node head;
static node tail;
// A function to convert given BST to Doubly
// Linked List. left pointer is used
// as previous pointer and right pointer
// is used as next pointer. The function
// sets *head to point to first and *tail
// to point to last node of converted DLL
static void convertBSTtoDLL(node root)
{
// Base case
if (root == null)
return;
// First convert the left subtree
if (root.left != null)
convertBSTtoDLL(root.left);
// Then change left of current root
// as last node of left subtree
root.left = tail;
// If tail is not null, then set right
// of tail as root, else current
// node is head
if (tail != null)
(tail).right = root;
else
head = root;
// Update tail
tail = root;
// Finally, convert right subtree
if (root.right != null)
convertBSTtoDLL(root.right);
}
// This function returns true if there
// is pair in DLL with sum equal to given
// sum. The algorithm is similar to hasArrayTwoCandidates()
// in method 1 of http://tinyurl.com/dy6palr
static bool isPresentInDLL(node head, node tail, int sum)
{
while (head != tail)
{
int curr = head.key + tail.key;
if (curr == sum)
return true;
else if (curr > sum)
tail = tail.left;
else
head = head.right;
}
return false;
}
// The main function that returns
// true if there is a 0 sum triplet in
// BST otherwise returns false
static bool isTripletPresent(node root)
{
// Check if the given BST is empty
if (root == null)
return false;
// Convert given BST to doubly linked list. head and tail store the
// pointers to first and last nodes in DLLL
head = null;
tail = null;
convertBSTtoDLL(root);
// Now iterate through every node and
// find if there is a pair with sum
// equal to -1 * heaf.key where head is current node
while ((head.right != tail) && (head.key < 0))
{
// If there is a pair with sum
// equal to -1*head.key, then return
// true else move forward
if (isPresentInDLL(head.right, tail, -1*head.key))
return true;
else
head = head.right;
}
// If we reach here, then
// there was no 0 sum triplet
return false;
}
// A utility function to create
// a new BST node with key as given num
static node newNode(int num)
{
node temp = new node();
temp.key = num;
temp.left = temp.right = null;
return temp;
}
// A utility function to insert a given key to BST
static node insert(node root, int key)
{
if (root == null)
return newNode(key);
if (root.key > key)
root.left = insert(root.left, key);
else
root.right = insert(root.right, key);
return root;
}
// Driver code
public static void Main(String[] args)
{
node root = null;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
if (isTripletPresent(root))
Console.Write("Present");
else
Console.Write("Not Present");
}
}
// This code is contributed by aashish1995
输出:
Present