Python Leetcode BST: Level Order Traversal - python

I am trying to solve the Leetcode problem: 102. Binary Tree Level Order Traversal and hit a snag. My code below does not give the correct output and I have been trying to figure out what is the issue since it is not appending the last level in the tree. I would appreciate it someone can assist in making this code work.
# 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 levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
while not root:
return []
queue = [root]
result = [[queue[0].val]]
while queue:
nodes = queue
level_nodes = []
temp = []
for node in nodes:
level = queue.pop(0)
if node.left:
level_nodes.append(level.left.val)
temp.append(node.left)
if node.right:
level_nodes.append(level.right.val)
temp.append(node.right)
queue = temp
result.append(level_nodes)
return result
Input: root = [3,9,20,null,null,15,7]
Expected Output: [[3],[9,20],[15,7]]
Output I am getting: [[3],[9,20],[]]
Reference: https://leetcode.com/problems/binary-tree-level-order-traversal/description/

I have been able to solve the problem and leave it for reference anyone who is doing it in this way (Not trying to use deque from collisions library). This solution was accepted by LeetCode.
# 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 levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
while not root:
return []
queue = [root]
result = []
while queue:
level_nodes = []
temp = []
for node in queue:
level_nodes.append(node.val)
if node.left:
temp.append(node.left)
if node.right:
temp.a bppend(node.right)
queue = temp
result.append(level_nodes)
return result

Related

how do I print the value of nodes in a binary tree, that have been added to a queue?

I am writing code to solve the following Leetcode solution:
https://leetcode.com/problems/symmetric-tree/
#THIS FIRST CHUNK OF CODE IS JUST TO BUILD A BINARY TREE!
from collections import deque
class TreeNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def insert(self, val):
# Compare the new value with the parent node
if self.val:
if val <= self.val:
if self.left is None:
self.left = TreeNode(val)
else:
self.left.insert(val)
elif val >= self.val:
if self.right is None:
self.right = TreeNode(val)
else:
self.right.insert(val)
else:
self.val = val
def PrintTree(self):
if self.left:
self.left.PrintTree()
print(self.val),
if self.right:
self.right.PrintTree()
#THIS IS THE CODE TO SOLVE THE LEETCODE PROBLEM
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
queue = deque()
if not root:
return []
if root.left:
queue.append(root.left)
if root.right:
queue.append(root.right)
right_subt = []
left_subt = []
while queue:
level_length = len(queue)
for _ in range(level_length // 2):
node = queue.popleft()
left_subt.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
for _ in range((level_length - (level_length // 2))):
node = queue.popleft()
right_subt.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
print(queue)
if left_subt != right_subt.reverse():
return False
return True
root = TreeNode(1)
root.insert(2)
root.insert(2)
root.insert(3)
root.insert(4)
root.insert(4)
root.insert(3)
root.PrintTree()
x=Solution()
Solution.isSymmetric(x,root)
My code fails the first input: root = [1,2,2,3,4,4,3] ; it should return True but it is retuning False, and I am trying to debug it.
In my code above I build a tree using class TreeNode, and I try to print the queue, however what I get is: deque([<__main__.TreeNode object at 0x7fe9381dc340>, <__main__.TreeNode object at 0x7fe9381dc820>])
Any ideas how I can print the queue to show the node values?
Most elegant would be to define the __repr__ function for the TreeNode class, e.g.
def __repr__(self):
return f"Node {self.val}"
This determines how the TreeNode class is printed. In this case you get
deque([Node 2, Node 3])
Then you can also adapt it according to your needs, e.g. if you want to print left and right in addition to the value.

Why does "temp" in this piece of code keep the value from the left side when doing right side?

# 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 pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
self.resultpath = []
def dfs(node,target,temp):
if node is None:
return
temp.append(node.val)
print(temp)
if node.left is None and node.right is None and target == node.val:
self.resultpath.append(temp)
dfs(node.left, target-node.val, temp)
dfs(node.right, target-node.val, temp)
dfs(root, targetSum, [])
return self.resultpath
this is really confusing me. For a "Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22"
picture of the tree: https://imgur.com/a/cAK8kQn
As this code goes through the recursions, at temp = [5,4,11], dfs(node.left ...) will turn this into [5,4,11,7] but temp is still [5,4,11], so dfs(node.right ...) should turn this into [5,4,11,2] but the 7 from dfs(node.left ...) shows up to make it [5,4,11,7,2].
Why is that? How would I fix this code so it doesn't do that?
The issue is quite simple. There is only a single temp. You are passing a reference to this single object in all recursive calls, so any mutations in a recursive call to dfs will be visible from the calling scope.
The key is to simply copy temp every time you make a recursive call.

How to traverse a tree with only one line? (python, tree traversal)

For a binary tree, we can traverse it in one line just like this (inorder, preorder, postorder is all ok):
# 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
# this is a preorder traversal with one line:
class Solution:
def preorderTraversal(self, root) -> List[int]:
return [] if root is None else [r.val] + self.preorderTraversal(r.left) + self.preorderTraversal(r.right)
For a tree that has multi-child in its node, how to complete the traversal work in one line?
I think list comprehension is a possible method, but I cannot complete the work in one line.
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def preorder(self, root: 'Node') -> List[int]:
if root is None: return []
ans = [root.val]
[ans.extend(x) for x in [self.preorder(child) for child in root.children]]
return ans
# This is a normal traversal:
# class Solution:
# def preorder(self, root: 'Node') -> List[int]:
# if root is None: return []
# ans = [root.val]
# for child in root.children:
# ans += self.preorder(child)
# return ans
Use a list comprehension to gather the traversal of all the root's children, regardless of how many children there are.
class Solution:
def preorderTraversal(self, root) -> List[int]:
# Original hard-coded approach for binary trees
# return [] if root is None else [r.val] \
# + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)
# Generalized approach for binary trees
# return [] if root is None else [r.val] \
# + [y for child in [root.left, root.right] for y in self.preorderTraversal(child)]
# Generalized approach for a tree with arbitrary children per node
return [] if root is None else ([root.val]
+ [y for child in root.children for y in self.preorderTraversal(child)])
It could work like this:
class Solution:
def preorder(self, root):
return [] if root is None else [root.val] + [value
for child in (root.children or [])
for value in self.preorder(child)]
The idea is that list comprehension replaces a repeated call to append, not to extend. The non-comprehension code, that maps to the above list comprehension version, is:
class Solution:
def preorder(self, root):
if root is None:
return []
res = [root.val]
for child in (root.children or []):
for value in self.preorder(child):
res.append(value)
return res

Python. I am trying to iteratively perform inorder Traversal of a tree, but I am going into an infinite loop

Below in the solution class, I have an implementation of an inorder traversal (left, root, right).
For some reason I am entering into an infinte loop and I wonder if it is becaue of the way python handels consecutive if if/else statements?
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = righ
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
out = []
stack = []
if root is None:
return out
else:
stack.append(root)
while stack != []:
temp = stack.pop()
if temp.right:
stack.append(temp.right)
if temp.left:
a = temp.left
stack.append(temp)
stack.append(a)
else:
out.append(temp.val)
return out

Level Order Traversal BST Code

I was wondering if someone can review my code for level order traversal in a BST. I am suppose to have [[3],[9,20],[15,7]] but instead I get [[3],[9],[20],[15],[7]] I know I need an outer while loop but, not sure how to construct it.
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
import queue
class Solution(object):
def levelOrder(self, root):
L = queue.Queue()
local = []
L.put(root)
while not L.empty():
node = L.get()
local.append([node.val])
if(node.left):
L.put(node.left)
if(node.right):
L.put(node.right)
return local

Categories