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.
Related
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
I am traversing a Binary Tree in an in-order manner to determine if it is a Binary Search Tree. Here is my code:
class T:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def is_bst(node):
if not node:
return
output = []
is_bst(node.left)
output.append(node.value)
is_bst(node.right)
print(output)
For the above example, the output = [1,3,2,9,7,5]
But this is clearly not correct! - I would usually debug but I am not familiar with running trees/binary trees as inputs. Any idea where my code is going wrong???
Updated code:
class T:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def inOrderTraversal(node,output):
if not node:
return None
is_bst(node.left)
output.append(node.value)
is_bst(node.right)
return
def is_bst(node):
output = []
inOrderTraversal(node,output)
print(output)
For the same example, the output = [1,3,2,9,7,5] is still wrong
You create your output inside the routine, so it's always empty. Then you add the current node's value but you print it at the end of the routine. The result is postorder, not inorder - each node is printed after both its subtrees.
Apart from the code structure your function has wrong name - you actually don't want it to answer whether the tree is BST, you just want it to return the contents:
def dump_tree_inorder(node, output):
if not node:
return
dump_tree_inorder(node.left, output)
output.append(node.value)
dump_tree_inorder(node.right, output)
I am writing some code for traversing a tree:
root = [1, None, 2, 3]
class Treenode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def post_order_traversal_iterative(self,root):
stack = [root]
output = []
if not root:
return []
while stack:
curr = stack.pop()
output.append(curr.val)
if curr.right:
stack.append(curr.right)
if curr.left:
stack.append(curr.left)
return output
x = Solution()
print(Solution.post_order_traversal_iterative(x,root))
But I am getting the error that a 'list object has no attribute val'- which I totally get, but then how do I pass in my list as the input??
There are a few issues in your code:
post_order_traversal_iterative expects a Treenode instance but you're passing it a list instead; you should do something like root = Treenode() and then x.post_order_traversal_iterative(root)
once again since you put on the stack the left and right values of the current node they too should be instances of Treenode, not integer
apart from being a list and not a Treenode your root contains four elements while three are requested
So assuming you were trying to create a mini tree with just a root node "1" with two children "2" and "3" you should have something like
rootnode = Treenode(val=1)
firstchild = Treenode(val=2)
secondchild = Treenode(val=3)
rootnode.left = firstchild
rootnode.right = secondchild
or more succinctly
rootnode = Treenode(val=1, left=Treenode(val=2), right=Treenode(val=3))
Leetcode 113 - Path Sum II
Given the root of a binary tree and an integer targetSum, return all root-to-leaf paths where each path's sum equals targetSum.
# 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]]:
if not root: return []
res = []
def dfs(node, total = 0, path = []):
if not node: return
path.append(node.val)
total += node.val
if not node.left and not node.right and total == targetSum:
res.append(list(path))
else:
dfs(node.left, total, path)
dfs(node.right, total, path)
total -= path.pop()
dfs(root)
return res
Why we have to use res.append(list(path)) rather than use res.append(path)?
If we only append path into res, it would only append empty list into res.
This is a subtle Python issue. When you use a default parameter like that (in the def dfs line), it captures that default object at definition time. So, every time that function runs, path is set to the SAME empty list. If you change that list, everyone with a reference to it sees the change. I believe they use list(path) to make a copy of that list, rather than store a link to the common list.
I have been trying to find an efficient and easy way to store the value of tree traversal (in order) in a list for further processing but I am not getting a proper way to perform it.
The reason I want it is to find the mode in the tree. I have tried global variables but I am not a fan of it, makes the code look bad.
I tried the yield function but that doesn't seem to do any good. (I have some hope left for this)
def inorder(self,root):
if not root:
return
self.inorder(root.left)
self.store(root.val)
self.inorder(root.right)
Thanks,
Prerit
If you're using Pyhotn 3.3+, you can use yield and yield from expressions:
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def inorder(self, root):
if not root:
return
yield from self.inorder(root.left)
yield root.val
yield from self.inorder(root.right)
# # For Python 3.2-
# for val in self.inorder(root.left):
# yield val
# yield root.val
# for val in self.inorder(root.right):
# yield val
Usage:
# Traverse
n = Node('top', Node('left'), Node('right'))
for val in n.inorder(n):
print(val)
# -> prints `left`, `top`, `right`
# get as a list
list(n.inorder(n)) # -> ['left', 'top', 'right']