I am testing the leetcode 104 Maximum Depth of Binary Tree. While testing the case root = [3,9,20,None, None,15,7] . The output should be 3 but it shows 2. Could someone help me with this. Thanks
class TreeNode:
def __init__(self,val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def createTreeNode(nodeList):
root = TreeNode(nodeList[0])
root.left = TreeNode(nodeList[1])
root.right = TreeNode(nodeList[2])
return root
def maxDepth(root):
if root is None:
return 0
else:
max_left = maxDepth(root.left)
max_right = maxDepth(root.right)
return max(max_left, max_right) + 1
def main():
ListNode1 = [3,9,20,None,None,15,7]
TreeNode1 = createTreeNode(ListNode1)
print (maxDepth(TreeNode1))
main()
You do not construct your tree in the right way. Leetcode recently added an option to visualize trees (see Tree Visualizer in the right-bottom corner of the Testcase tab). For your input:
In test cases usually trees are represented as in-order traversal, so you can build up a tree from it using suitable traversal algorithm or you could build it manually:
root = TreeNode(3)
root.left = TreeNode(9)
root.right = TreeNode(20)
root.right.right = TreeNode(7)
root.right.left = TreeNode(15)
Your algorithm is correct, but I would refactor it a bit:
def maxDepth(root):
if not root:
return 0
max_left = maxDepth(root.left)
max_right = maxDepth(root.right)
return max(max_left, max_right) + 1
Related
I'm trying to solve the following problem.
Given the root of a binary tree, construct a 0-indexed m x n string matrix res that represents a formatted layout of the tree. The formatted layout matrix should be constructed using the following rules:
The height of the tree is height and the number of rows m should be equal to height + 1.
The number of columns n should be equal to 2**(height+1) - 1.
Place the root node in the middle of the top row (more formally, at location res[0][(n-1)/2]).
For each node that has been placed in the matrix at position res[r][c], place its left child at res[r+1][c-2height-r-1] and its right child at res[r+1][c+2**(height-r-1)].
Continue this process until all the nodes in the tree have been placed.
Any empty cells should contain the empty string "".
Return the constructed matrix res.
This is my code:
# 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
def find_h(node: Optional[TreeNode]) -> int:
if not node:
return 0
return 1 + max(find_h(node.left), find_h(node.right))
class Solution:
def printTree(self, root: Optional[TreeNode]) -> List[List[str]]:
height = find_h(root)
res = [['' for _ in range(2 ** height - 1)] for _ in range(height)]
def dispNode(node: Optional[TreeNode], r: int, c: int):
res[r][c] = str(node.val)
if node.left:
dispNode(node.left, r + 1, c - 2**(height-r-2))
if node.right:
dispNode(node.right, r + 1, c + 2**(height-r+2))
dispNode(root, 0, 2**(height - 1) - 1)
return res
I get an index out of bounds error and if I use a try-except block on the res[r][c] = str(node.val) line, I still only get the left nodes only. Is there something wrong with the way variable scopes are working?
Given a binary tree, a target node in the binary tree, and an integer value k, find all the nodes that are at distance k from the given target node. No parent pointers are available.
link to the problem on GFG: LINK
Example 1:
Input :
20
/ \
8 22
/ \
4 12
/ \
10 14
Target Node = 8
K = 2
Output: 10 14 22
Explanation: The three nodes at distance 2
from node 8 are 10, 14, 22.
My code
from collections import defaultdict
class solver:
def __init__(self):
self.vertList = defaultdict(list)
def addEdge(self,u,v):
self.vertList[u].append(v)
def makeGraph(self,root):
visited = set()
queue = []
queue.append(root)
while len(queue) > 0:
curr = queue.pop(0)
visited.add(curr)
if curr.left is not None and curr.left not in visited:
self.vertList[curr.data].append(curr.left.data)
self.vertList[curr.left.data].append(curr.data)
queue.append(curr.left)
if curr.right is not None and curr.right not in visited:
self.vertList[curr.data].append(curr.right.data)
self.vertList[curr.right.data].append(curr.data)
queue.append(curr.right)
def KDistanceNodes(self,root,target,k):
self.makeGraph(root)
dist = {}
for v in self.vertList:
dist[v] = 0
visited2 = set()
queue2 = []
queue2.append(target)
while len(queue2) > 0:
curr = queue2.pop(0)
visited2.add(curr)
for nbr in self.vertList[curr]:
if nbr not in visited2:
visited2.add(nbr)
queue2.append(nbr)
dist[nbr] = dist[curr] + 1
ans = []
for v in dist:
if dist[v] == k:
ans.append(str(v))
return ans
#{
# Driver Code Starts
#Initial Template for Python 3
from collections import deque
# Tree Node
class Node:
def __init__(self, val):
self.right = None
self.data = val
self.left = None
# Function to Build Tree
def buildTree(s):
# Corner Case
if (len(s) == 0 or s[0] == "N"):
return None
# Creating list of strings from input
# string after spliting by space
ip = list(map(str, s.split()))
# Create the root of the tree
root = Node(int(ip[0]))
size = 0
q = deque()
# Push the root to the queue
q.append(root)
size = size + 1
# Starting from the second element
i = 1
while (size > 0 and i < len(ip)):
# Get and remove the front of the queue
currNode = q[0]
q.popleft()
size = size - 1
# Get the current node's value from the string
currVal = ip[i]
# If the left child is not null
if (currVal != "N"):
# Create the left child for the current node
currNode.left = Node(int(currVal))
# Push it to the queue
q.append(currNode.left)
size = size + 1
# For the right child
i = i + 1
if (i >= len(ip)):
break
currVal = ip[i]
# If the right child is not null
if (currVal != "N"):
# Create the right child for the current node
currNode.right = Node(int(currVal))
# Push it to the queue
q.append(currNode.right)
size = size + 1
i = i + 1
return root
if __name__ == "__main__":
x = solver()
t = int(input())
for _ in range(t):
line = input()
target=int(input())
k=int(input())
root = buildTree(line)
res = x.KDistanceNodes(root,target,k)
for i in res:
print(i, end=' ')
print()
Input:
1 N 2 N 3 N 4 5
target = 5
k = 4
Its Correct output is:
1
And Your Code's output is:
[]
My logic:
-> First convert the tree into a undirected graph using BFS / level order traversal
-> Traverse the graph using BFS and calculate the distance
-> Return the nodes at k distance from the target
What I think:
First of all in the given test case the tree representation seems to be in level order however, in the failing test case it doesn't look like level order or maybe my logic is wrong?
Input Format:
Custom input should have 3 lines. First line contains a string representing the tree as described below. Second line contains the data value of the target node. Third line contains the value of K.
The values in the string are in the order of level order traversal of the tree where, numbers denote node values, and a character āNā denotes NULL child.
For the above tree, the string will be: 1 2 3 N N 4 6 N 5 N N 7 N
The mistake is that the logic that is done in "init" should be done for every use-case (reinitializing self.vertList), not just once at the beginning.
Change:
def __init__(self):
self.vertList = defaultdict(list)
to:
def __init__(self):
pass
and:
def KDistanceNodes(self,root,target,k):
self.makeGraph(root)
dist = {}
...
to:
def KDistanceNodes(self, root, target, k):
self.vertList = defaultdict(list) # <-- move it here
self.makeGraph(root)
dist = {}
...
The original code kept accumulating the nodes and "remembered" the previous use-cases.
Also pay attention that you should return ans sorted, meaning that you should not append the numbers as strings so that you'll be able to sort them, change: ans.append(str(v)) to: ans.append(v) and return sorted(ans).
I am novice to recursion, I have written code to find the path of a given node, when I dry run my code(trace the stack) it is giving the right answer but when I am running the same on machine it is not showing the expected output can someone please help me in tracing out the code(e.g. using the call stack)?
class NewNode:
def __init__(self, data):
self.data = data
self.left = self.right = None
arr = [1, 2, 3, 4, 5, 6, 7]
q = []
def create_level_order_binary_tree(i):
root = None
if i < len(arr):
root = NewNode(arr[i])
root.left = create_level_order_binary_tree(2 * i + 1)
root.right = create_level_order_binary_tree(2 * i + 2)
return root
def dfs(root, p, temp_path, path):
print(temp_path)
if root is None:
return path
if root.data == p:
if len(temp_path) == 0:
path.append(root.data)
return path
else:
temp_path.append(root.data)
path.append(temp_path)
return path
temp_path.append(root.data)
path = dfs(root.left, 6, temp_path, path)
if len(path) == 0:
path = dfs(root.right, 6, temp_path, path)
return path
root_node = create_level_order_binary_tree(0)
path_to_node = dfs(root_node, 6, [], [])
print(path_to_node`enter code here`)
The following are two approaches to solving your problem. While I haven't timed the routines, I suspect the non-recursive approach will be faster, since it doesn't utilize the stack as much.
First using a non-recursive approach employing a simple stack (Last In First Out) data structure.
from copy import deepcopy
def nrc_dfs(nde, p):
stck = [(nde, [])] #LIFO stack implementation
while stck:
nd, pth = stck.pop(len(stck)-1) #pop lastv entry
if nd:
pth.append(nd.data)
if nd.data == p:
return pth
stck.append((nd.right, deepcopy(pth)))
stck.append((nd.left, deepcopy(pth)))
return []
The second approach, using a recursive technique.
def rc_dfs(nde, p):
def dfs_sch(nde, p, path):
if nde:
path.append(nde.data)
if nde.data == p:
return path
pl = dfs_sch(nde.left, p, [])
if pl:
path.extend(pl)
return path
pr = dfs_sch(nde.right, p, [])
if pr:
path.extend(pr)
return path
return []
return dfs_sch(nde, p, [])
I want to be able to recursively find the sum of all the leaves in a binary tree through the use of nodes so far I have:
class BTNode:
"""A node in a binary tree."""
def __init__(self: 'BTNode', item: object,
left: 'BTNode' =None, right: 'BTNode' =None) -> None:
"""Initialize this node.
"""
self.item, self.left, self.right = item, left, right
def __repr__(self):
return 'BTNode({}, {}, {})'.format(repr(self.item),
repr(self.left), repr(self.right))
def is_leaf(self: 'BTNode') -> bool:
return not self.left and not self.right
def tree_sum(t: BTNode) -> int:
'''Return the sum of the leaves in t.
>>> t = BTNode(None, BTNode(8), BTNode(9))
>>> tree_sum(t)
17
'''
sm = 0
t1 = t.left.item
t2 = t.right.item
if not t.left or not t.right:
return 0
if t.left.is_leaf() and t.right.is_leaf():
sm = t1 + t2 + tree_sum(t.left) + tree_sum(t.right)
return sm
The function tree_sum(t) I have doesn't work, I'm struggling to find a way that works. What am i doing incorrectly?
You are missing a tiny bit of code.
Since t.left and t.right will be None if t is a leaf, the lines t1 = t.left.item and t2 = t.right.item will raise an AttributeError.
You need to take that into account:
t1 = t.left.item if t.left else None
t2 = t.right.item if t.right else None
Then
t = BTNode(None, BTNode(8), BTNode(9))
print(tree_sum(t))
produces the correct result (17).
That said, this function will not return the sum of all leaves (ie it won't traverse the whole tree in case of a multi-level tree).
I'm a beginner in programming, and I couldn't find the answer in other questions.
I'd like to create an empty binary tree of height h.
My code:
class node:
def __init__(self, a = None):
self.value = a
self.left = None
self.right = None
def postorder(tree,abba):
if tree != None:
postorder(tree.left,abba)
postorder(tree.right,abba)
abba.append(tree.value)
def inorder(tree,abba):
if tree != None:
inorder(tree.left,abba)
abba.append(tree.value)
inorder(tree.right,abba)
I would like to define a function
def getBinaryTree(h):
That gives me a tree with level h. So:
empty tree of level
Any ideas?
Updated
To make a binary tree with height h, you need to add 2^(h+1)-1 nodes. A tree with height 0 means, the tree contains only one node and that is the root. For example, to create a tree with height 3, you need to add 2^(3+1)-1 = 15 nodes.
If you want to create a set of nodes which can form a binary tree with your given code, you can do something like this.
import math
class node:
def __init__(self, a = None):
self.value = a
self.left = None
self.right = None
def getBinaryTree(tree_height):
tree_nodes = [None] * int((math.pow(2, tree_height+1) - 1))
for i in range(tree_height):
start_index = int(math.pow(2, i) - 1)
end_index = int(math.pow(2, i+1) - 1)
for j in range(start_index, end_index):
tree_nodes[j] = node(j)
if j == 0: continue
if j % 2 == 0: # a right child
parent_index = int((j - 2) / 2)
tree_nodes[parent_index].right = tree_nodes[j]
else: # a left child
parent_index = int((j - 1) / 2)
tree_nodes[parent_index].left = tree_nodes[j]
return tree_nodes[0] # returns the root node
def printTree(tree_node, inorder_tree_walk):
if tree_node != None:
printTree(tree_node.left, print_tree)
inorder_tree_walk.append(tree_node.value)
printTree(tree_node.right, print_tree)
root = getBinaryTree(4)
inorder_tree_walk = []
printTree(root, inorder_tree_walk)
print(inorder_tree_walk)
So, what the program does?
The program creates 2^(h+1)-1 nodes to form a tree with height h. Nodes are stored in list tree_nodes. Parent-child relationship between nodes are stored in tree_nodes as follows.
Left child of element i: (2i + 1)th element
Right child of element i: (2i + 2)th element
When a children node is created, it is set as a left/right children of its parent.