Check if a Binary Tree is Balanced or not - python

I tried to solve this question in LeetCode, even though my solution was right, one particular test case has failed.
My Code :
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def isBalanced(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
#height,flag = self.dfs(root)
return self.dfs(root)[1]
def dfs(self,node,isTreeBalanced=True):
if node is None or not isTreeBalanced:
return 0,isTreeBalanced
leftHeight , isTreeBalanced = self.dfs(node.left,isTreeBalanced)
rightHeight, isTreeBalanaced = self.dfs(node.right,isTreeBalanced)
print(abs(leftHeight-rightHeight))
if abs(leftHeight - rightHeight) > 1:
isTreeBalanced = False
return max(leftHeight,rightHeight)+1 , isTreeBalanced
Test Case Input for which my Code failed:
[1,2,3,4,5,null,6,7,null,null,null,null,8]
Leetcode question : Check if the Tree is Balanced or not
Can anyone help in identifying the issue? Is there any edge case I am missing ?

Your code is correct and you have not missed any testcase, it is just that you have misspelled the isTreeBalanced as isTreeBalanaced which is why you were getting the testcase failed which was having only nodes on left and just one node on right.
Although I solved this entire question and here is my code for the above question:
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
self.Balanced = True
if not root:
return self.Balanced
self.maxDepth(root)
return self.Balanced
def maxDepth(self, root):
if not root:
return 0
else:
ldepth = self.maxDepth(root.left)
rdepth = self.maxDepth(root.right)
if abs(ldepth - rdepth) >= 2:
self.Balanced = False
return max(ldepth, rdepth) + 1
Time Complexity : O(N)
Space Complexity : O(N) (For call stack)

Related

Count Nodes Equal to Average of Subtree

I'm the beginner for python,and I always feel confused about binary tree when I practise in leetcode.
Here is my code:
from typing import Optional
#Definition for a binary tree node.(This is given by leetcode)
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution(object):
def averageOfSubtree(self, root: Optional[TreeNode]) -> int:
ans = 0
def traverse(node):
if node is None:
return (0,0)
left = traverse(node.left)
right = traverse(node.right)
total = left[0] + right[0] + node.val
count = left[1] + right[1] +1
if total // count == node.val:
nonlocal ans
ans += 1
return (total, count)
traverse(root)
return ans
root = [4,8,5,0,1,None,6]
a = Solution()
print(a.averageOfSubtree(root))
The TreeNode definition is given by leetcode, and I just copy down and run on my vscode, however, it hint an error:AttributeError: 'list' object has no attribute 'left'
How can I modify it?

Understanding overriding in in-order tree traversal

I am looking to return the k-th element of a binary tree and came up with this solution:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
if not root:
return None
out = []
return self.Search(root,k,out)[k-1]
def Search(self,root,k,out):
if root:
# iterate over the tree using DFS, and after the last iteration return the sorted list "out"
self.Search(root.left,k,out)
self.Search(root.right,k,out)
out.append(root.val)
return sorted(out)
My question is: Why can't I return sorted(out)[k-1] in the Search method? I have to return the sorted list to the kthSmallest method and then search for the k-th entry and I don't understand why.

Leetcode sum of left subtree getting error

The below code works fine for sample input but provides the wrong answer for
[1,2,3,4,5]
excepted answer:4
program output: 6
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if not root: return 0
sum=0
a=deque([root])
while a:
for i in range(len(a)):
node=a.popleft()
if node.left:
sum+=node.left.val
a.(node.left)
if node.right:
a.append(node.right)
return sum

How to find max depth of n-ary tree using bfs?

This is my node definition :
class Node(object):
def __init__(self, val, children):
self.val = val
self.children = children
Now I've to find max depth in the tree. I'm using breadth-first search to mark the level of each node, then returning the max of levels.
This is my code :
def maxDepth(self, root):
"""
:type root: Node
:rtype: int
"""
if(root == None):
return 0
q = []
q.append(root)
level={root.val:1}
while(len(q)>0):
s = q.pop(0)
for c in s.children:
q.append(c)
level[c.val]=level[s.val]+1
return max(level.values())
It's working on some cases but giving the wrong answer in many cases. I don't understand where I'm missing the concept?
As suggested by #pfctgeorge, i was appending level according to node value, but there can be multiple nodes with same value as it's a tree, it'll give wrong answer in that cases.
Since you know where you went wrong, you could do something like below to achieve max depth of the tree-
Pseudocode:
q = []
q.offer(root)
level = 1
while q.isEmpty() == false:
size = q.size()
for i = 0 to size:
curr_node = q.poll()
for each_child in curr_node:
q.offer(each_child)
level = level + 1
return level

Find number of elements smaller than a given element in BST

I have been struggling with this problem for a while and I am a Python beginner when it comes to BST, so I would appreciate some help. I am dynamically adding elements from an (unsorted) array into BST. That part is fine, I know how to do that. The next step, proved to be impossible with my current skill set. As I am adding elements to the tree, I need to be able to find current rank of any element in the tree. I know there are subtleties in this problem, so I would need help to at least find the number of nodes that are below the given node in BST. For example, in this case, node 15 has nodes 10,5 and 13 below it, so the function will return 3. Here is my existing code [this is a problem from Cracking the coding interview, chapter 11]
class Node:
"""docstring for Node"""
def __init__(self, data):
self.data = data
self.left=None
self.right=None
self.numLeftChildren=0
self.numRightChildren=0
class BSTree:
def __init__(self):
self.root = None
def addNode(self, data):
return Node(data)
def insert(self, root, data):
if root == None:
return self.addNode(data)
else:
if data <= root.data:
root.numLeftChildren+=1
root.left = self.insert(root.left, data)
else:
root.numRightChildren+=1
root.right = self.insert(root.right, data)
return root
def getRankOfNumber(self,root,x):
if root==None:
return 0
else:
if x>root.data :
return self.getRankOfNumber(root.right,x)+root.numLeftChildren+1
elif root.data==x:
return root.numLeftChildren
else:
return self.getRankOfNumber(root.left,x)
BTree=BSTree()
root=BTree.addNode(20)
BTree.insert(root,25)
BTree.insert(root,15)
BTree.insert(root,10)
BTree.insert(root,5)
BTree.insert(root,13)
BTree.insert(root,23)
You can go by this approach:
1. Have 2 more fields in each node numLeftChildren and numRightChildren.
2. Initialize both of them to 0 when you create a new node.
3. At the time of insertion, you make a comparison if the newly added node's
key is less than root's key than you increment, root's numLeftChildren and
call recursion on root's left child with the new node.
4. Do Same thing if new node's key is greater than root's key.
Now, come back to your original problem, You have to find out the number of children in left subtree. Just find out that node in O(logN) time and just print the numLeftChildren
Time Complexity: O(logN)
PS: I have added another field numRightChildren which you can remove if you are always interested in knowing the number of nodes in left subtree only.
You could modify your BST to contain the number of nodes beneath each node.
Or you could iterate over a traditional BST from least to greatest, counting as you go, and stop counting when you find a node of the required value.
You could simplify the code by using just instances of the Node class, as your BSTree instance operates on the root node anyway. Another optimization could be to not represent duplicate values as separate nodes, but instead use a counter of occurrences of the key:
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
self.num_left_children = 0
self.occurrences = 1
def insert(self, data):
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
self.num_left_children += 1
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.occurrences += 1
def get_rank(self, data):
if data < self.data:
return self.left.get_rank(data)
elif data > self.data:
return (self.occurrences + self.num_left_children +
self.right.get_rank(data))
else:
return self.num_left_children
Demo:
root = Node(20)
root.insert(25)
root.insert(15)
root.insert(10)
root.insert(10)
root.insert(5)
root.insert(13)
root.insert(23)
print(root.get_rank(15)) # 4
You can use the below function to find the number of the nodes in the tree (including the root).
def countNodes(self, root):
if root == None:
return 0
else
return (1 + countNodes(root.left) + countNodes(root.right));
To find the number of nodes that lie below root, subtract 1 from the value returned by the function. I think this will help get you started on the problem.
Your code will look like:
class Node:
"""docstring for Node"""
def init(self, data):
self.data = data
self.left=None
self.right=None
self.depth=0
class BSTree:
def init(self):
self.root = None
def addNode(self, data):
return Node(data)
def insert(self, root, data):
if root == None:
return self.addNode(data)
else:
if data <= root.data:
root.left = self.insert(root.left, data)
else:
root.right = self.insert(root.right, data)
return root
BTree=BSTree()
root=BTree.addNode(20)
BTree.insert(root,25)
BTree.insert(root,15)
BTree.insert(root,10)
BTree.insert(root,5)
BTree.insert(root,13)
BTree.insert(root,23)
BTree.insert(root,23)
numLeft = countNodes(root->left);
numRight = countNodes(root->right);
numChildren = numLeft + numRight;

Categories

Resources