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;
}
};
Related
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)
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;
}
Question: Implement Inorder Traversal iteratively.
My Attempt: (results in an infinite loop that I haven't been able to debug) any help or suggestions greatly appreciated
/**
* 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) {}
* };
*/
#include <vector>
#include <stack>
#include <unordered_set>
using namespace std;
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
//iterative sol:
vector<int> sol;
stack<TreeNode*> dfs;
dfs.push(root);
unordered_set<TreeNode*> visited;
visited.insert({root});
TreeNode* temp;
while (!dfs.empty()) {
if (dfs.top()->left != nullptr && visited.find(dfs.top()->left) == visited.end()) {
dfs.push(dfs.top()->left);
visited.insert({dfs.top()->left});
}
else {
sol.push_back(dfs.top()->val);
temp = dfs.top();
dfs.pop();
if (temp->right != nullptr && visited.find(temp->right) == visited.end()) {
dfs.push(temp->right);
visited.insert({temp->right});
}
}
}
return sol;
}
};
EDIT: I don't have the specific internal definitions of the TreeNode, but if you want to run the problem, checkout: https://leetcode.com/problems/binary-tree-inorder-traversal/
Here is the problem :
dfs.push(dfs.top()->left);
visited.insert(dfs.top()->left);
You are pushing to stack (then dfs.top() will change) and then accessing dfs.top()->left in the next line.
You are modifying the stack in the first line here
dfs.push(dfs.top()->left);
visited.insert({dfs.top()->left});
what you want to do is to mark the previous dfs.top()->left as visited, but you are adding more element on top of the stack and thus the new dfs.top() is a different one.
To solve this problem you should use store the previous dfs.top()->left in a different variable.
As a best practice, the variable or object you are working on should be immutable, since the stack is not immutable don't use its top while inserting into it or doing some other computations. Instead store your required variable into something immutatble like temp here
temp = dfs.top();
if (temp->left != nullptr && visited.find(temp->left) == visited.end()) {
dfs.push(temp->left);
visited.insert({temp->left});
}
else {
sol.push_back(dfs.top()->val);
dfs.pop();
if (temp->right != nullptr && visited.find(temp->right) == visited.end()) {
dfs.push(temp->right);
visited.insert({temp->right});
}
}
It only takes 2 simple rules to implement an iterative in-order traversal.
If you're at node X, then:
If X has a right child, then move to the right child, and follow as many left links as possible to find the next node.
Otherwise, find the closest ancestor of X on the right, i.e., the closest ancestor whose left subtree contains X. If there is no such ancestor then you're done.
If your tree doesn't have parent links, then you'll need a stack to store the right ancestors, but there's no need for a visited set:
vector<int> inorderTraversal(TreeNode* tree) {
vector<int> ret;
stack<TreeNode *> nextParents;
for(;tree; tree = tree.left) {
nextParents.push(tree);
}
while(!nextParents.empty()) {
tree = nextParents.pop();
ret.push_back(tree->val);
for(tree = tree.right; tree; tree = tree.left) {
nextParents.push(tree);
}
}
return ret;
}
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
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.