How to balance a Binary Search Tree? - c++

I'm practicing binary tree problems on LeetCode and I'm struggling at the moment with balancing a binary search tree. I feel as if I got the logic of it, but I'm getting weird errors when using pointers.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void inOrder(TreeNode* root, vector<int> bst)
{
if (root != NULL)
{
inOrder(root->left, bst);
bst.push_back(root->val);
inOrder(root->right, bst);
}
}
TreeNode* Insert(TreeNode* bt, int median)
{
if (bt == NULL)
{
return new TreeNode(median);
}
if (median > bt->val)
{
bt->right = Insert(bt->right, median);
}
else
{
bt->left = Insert(bt->left, median);
}
return bt;
}
TreeNode* balanceBST(TreeNode* root) {
vector<int> sortedBST;
inOrder(root, sortedBST);
int size = sortedBST.size();
TreeNode* balancedBST;
int mid;
while (size != 0)
{
if (size % 2 == 1 || size % 2 == 0)
mid = size/2;
if (balancedBST == NULL)
{
balancedBST = new TreeNode(sortedBST[mid]);
}
else
{
TreeNode* node = Insert(balancedBST, sortedBST[mid]);
}
sortedBST.erase(sortedBST.begin() + mid);
--size;
}
return balancedBST;
}
};
The error I received was this:
=================================================================
==30==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc15eb8028 at pc 0x000000374488 bp 0x7ffc15eb7dd0 sp
0x7ffc15eb7dc8 READ of size 8 at 0x7ffc15eb8028 thread T0
#5 0x7fac728370b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) Address 0x7ffc15eb8028 is located in stack of thread T0 at offset 72
in frame This frame has 1 object(s):
[32, 112) 'q' <== Memory access at offset 72 is inside this variable HINT: this may be a false positive if your program uses some
custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions are supported)

Related

112.path sum leetcode wong answer for two test cases

problem My code fails for the following test case. I don't understand why. Can you tell me where I went wrong? My code passes (114/116) test cases. I'm doing DFS and checking whether currSum==targetSum and if it satisfies this condition and it's also a leaf node I'm setting global variable ```flag=true``.
[1,-2,-3,1,3,-2,null,-1]
-1
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool flag=false;
void dfs(TreeNode *root, int currSum, int targetSum){
if(root==NULL) return ;
// cout<<currSum<<" ";
currSum+=root->val;
cout<<currSum<<" ";
if(currSum == targetSum) {
if(root->left==NULL && root->right==NULL) flag=true;
return;
}
// else if(abs(currSum)>abs(targetSum)) return;
dfs(root->left,currSum,targetSum);
dfs(root->right,currSum,targetSum);
}
bool hasPathSum(TreeNode* root, int targetSum) {
int currSum=0;
dfs(root,currSum,targetSum);
return flag;
}
};
Here is a simple intuitive solution for Path Sum Leetcode
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if(!root) return false;
if(!root->right && !root->left) return root->val==sum;
return hasPathSum(root->left, sum-root->val) ||
hasPathSum(root->right, sum-root->val);
}
};
The code works fine and the logic is perfect, you forgot to put brackets to the if statement
if(root->left == NULL && root->right == NULL) {
flag=true;
return;
}
Here's the full code
class Solution {
public:
bool flag = false;
void dfs(TreeNode *root, int currSum, int targetSum){
if(root == NULL) return ;
currSum += root->val;
if(currSum == targetSum) {
if(root->left==NULL && root->right==NULL) {
flag=true;
return;
}
}
dfs(root->left,currSum,targetSum);
dfs(root->right,currSum,targetSum);
}
bool hasPathSum(TreeNode* root, int targetSum) {
int currSum=0;
dfs(root,currSum,targetSum);
return flag;
}
};
if(root->left==NULL && root->right==NULL) flag=true;
return;
This is wrong. You will return even if the condition doesn't satisfy. As there are negative values, it might be possible that the sum becomes targetSum again at a leaf node after further operations.
Correct:
if(root->left==NULL && root->right==NULL){
flag = true;
return;
}

My code is showing 'true' as output instead of 'False'

So there is a question in Leetcode in which we need to tell whether two binary trees are identical or not. So my function is working correctly for the inputs [1,2,3] and [1,2,3]
but it is printing 'true' for the inputs [1,2] and [1,NULL,2] instead of printing 'false'. Please can anyone tell me what have i done wrong in this program.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* enter code here TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution
{
public:
bool isSameTree(TreeNode *p, TreeNode *q)
{
if (p == NULL && q == NULL)
return true;
if (p != NULL && q != NULL)
{
if (p->val != q->val)
return false;
else
{
isSameTree(p->left, q->left);
isSameTree(p->right, q->right);
}
return true;
}
else
return false;
}
};
You're completely ignoring the results of those recursive calls. The point using recursion here is that two trees are the same if:
Their values are the same AND
Their respective children are the same.
You're testing the former, but never reaping the results of the latter. In reality, what you really should be trying to do is this:
class Solution
{
public:
bool isSameTree(const TreeNode *p, const TreeNode *q)
{
if (p == q) // same actual tree or both NULL
return true;
if (p != NULL && q != NULL)
{
return p->val == q->val &&
isSameTree(p->left, q->left) &&
isSameTree(p->right, q->right);
}
return false;
}
};

Vertical Order Traversal of B-Tree -> Error "Line 924: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h)"

I am getting runtime error while running the following code on leetcode.The problem involves finding the Vertical Traversal of a binary Tree.
I am getting the following error:
Line 1034: Char 9: runtime error: reference binding to null pointer of type 'std::vector<int, std::allocator>' (stl_vector.h) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:9
Problem link - https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree/
My Code :
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> verticalTraversal(TreeNode* root)
{
vector<vector<int>> ans;
map<int, vector<int>> mp;
if(root == NULL)
return ans;
queue<pair<TreeNode* , int>> q;
q.push({root,0});
while(!q.empty())
{
auto p= q.front();
TreeNode *curr = p.first;
int hd= p.second;
q.pop();
if(root->left != NULL)
{
q.push({root->left, hd-1});
}
if(root -> right != NULL)
{
q.push({root->right, hd+1});
}
ans[hd].push_back(curr->val);
}
return ans;
}
};

Error showing throwing an instance of std::out_of_range

I am solving leetcode question : Cousins in Binary Tree
Link for problem statement: https://leetcode.com/problems/cousins-in-binary-tree/
Logic:
Implementing bfs from root node and storing the distance of each child node from the root node in a "dis" vector and storing each node's parent node in a vector "pred" .
If parent node is not same and distance of x and y in function isCousin is same , then return true else false.
MY CODE:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> dis={0};
vector<int> pred={-1};
// vector<bool> vis={false};
struct TreeNode *temproot,*curr;
void bfs(TreeNode *root){
queue<TreeNode*> q;
int initDis=0;
q.push(root);
// vis.push_back(true);
dis.push_back(0);
pred.push_back(-1);
while(!q.empty()){
curr=q.front();
q.pop();
initDis += 1;
if(curr->left != NULL){
pred.push_back(curr->val);
temproot=curr->left;
// vis.push_back(true);
dis.push_back(initDis);
q.push(temproot);
}
else continue;
if(curr->right != NULL){
pred.push_back(curr->val);
temproot=curr->right;
// vis.push_back(true);
dis.push_back(initDis);
q.push(temproot);
}
else continue;
}
}
bool isCousins(TreeNode* root, int x, int y) {
if(root==NULL) return false;
bfs(root);
if(pred.at(x-1) == pred.at(y-1)) return false;
else
if(dis.at(x-1) == dis.at(y-1)) return true;
else return false;
}
};
ERROR MESSAGE:
Runtime Error Message:
terminate called after throwing an instance of 'std::out_of_range'
Last executed input:
[1,2,3,null,4,null,5]
5
4

C++ Binary Tree Traversal Inorder, Preorder and Postorder

I'm currently working on a C++ project and part of it is to traverse the binary tree using inorder, preorder, and postorder.
class TNode
{
public:
int val;
TNode() {}
TNode(int v) { val = v; }
TNode * left;
TNode * right;
TNode * parent;
};
class BTree
{
void print_pre_order(TNode *r);// print the node as you traverse according to the order.
void print_in_order();
void print_post_order();
}
BTree::BTree()
{
root = new TNode(1);
root->parent = 0;
root->left = new TNode(2);
root->right = new TNode(3);
root->left->left = new TNode(4);
root->left->right = new TNode (5);
root->right->left = new TNode(6);
}
void BTree::print_pre_order(TNode *r)
{
if (r == 0)
{
return;
}
cout << r->val;
print_pre_order(r->left);
print_pre_order(r->right);
}
int main()
{
BTree y;
y.print_pre_order(y.root);
return 0;
}
In my default constructor, I've initialized values for some nodes, but when I run the code, the output I'm getting is "124" and gets an error. I don't know where I did wrong, can someone help?
I see no signs that the program ever sets any any pointers to zero, so if (r == 0) is unlikely to ever trigger an exit.
Give this a try:
class TNode
{
public:
int val;
TNode(): val(0), left(nullptr), right(nullptr), parent(nullptr) {}
TNode(int v): val(v), left(nullptr), right(nullptr), parent(nullptr) {}
TNode * left;
TNode * right;
TNode * parent;
};
The : tells the compiler that a member initializer list is coming. After that the code initializes all of the pointer members to point at null.
Change the
if (r == 0)
to
if (r == nullptr)
to better convey intent and you should be good to go.