How does "if right and left: return root" and the "return right or left" help us find the least common ancestor? - binary-tree

class TreeNode:
def __init__(self, data, left = None, right = None):
self.data = data
self.left = left
self.right = right
def insert(temp,data):
que = []
que.append(temp)
while (len(que)):
temp = que[0]
que.pop(0)
if (not temp.left):
if data is not None:
temp.left = TreeNode(data)
else:
temp.left = TreeNode(0)
break
else:
que.append(temp.left)
if (not temp.right):
if data is not None:
temp.right = TreeNode(data)
else:
temp.right = TreeNode(0)
break
else:
que.append(temp.right)
def make_tree(elements):
Tree = TreeNode(elements[0])
for element in elements[1:]:
insert(Tree, element)
return Tree
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
if not root:
return None
if root.data == p or root.data ==q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
**if right and left:
return root**
*return right or left*
ob1 = Solution()
tree = make_tree([3,5,1,6,2,0,8,None,None,7,4])
print(ob1.lowestCommonAncestor(tree, 5, 1).data)
Why do we return right or left when we want to return a single node rather than two?
I realized that the boolean "right and left" returns true even if right and left are not the same TreeNode. Also, there's no comparison function written. Is that necessary?

return right or left returns right if it is not None, otherwise, it checks left and returns left, if it's not None. If both left and right are None returns None. So, only one node or None is returned.
if right and left is True only if both left and right are not None

Related

Tree from balanced parenthesis

I have to find height of tree and find protection number (or just to generate a tree) from balanced parentheses.
For example:
()()()() creates tree like a list with height 3.
I have no idea how to convert parentheses to tree. I found some 'answers':
http://www.cs.utsa.edu/~wagner/knuth/fasc4a.pdf (second page contains all examples for tree with 4 nodes)
paragraph - Binary Trees, Forests, Non-Crossing Pairs :
https://sahandsaba.com/interview-question-generating-all-balanced-parentheses.html
However, I still don't know how to create a tree from such defined parentheses. I have some impression that in Knuth, authors treat it as something obvious.
Do I miss something or it's not that simple?
Is it necessary to create a forest and then a binary tree?
A pair of parentheses represents a node. What appears within those parentheses represents its left child's subtree (according to the same rules). What appears at the right of those parentheses represents the node's right child's subtree (again, according to the same rules).
The conversion of this encoding into a binary tree can be done recursively like this:
function makeBinaryTree(input):
i = 0 # character index in input
function recur():
if i >= input.length or input[i] == ")":
i = i + 1
return NIL
i = i + 1
node = new Node
node.left = recur()
if i >= input.length or input[i] == ")":
i = i + 1
return node
node.right = recur()
return node
return recur()
Here is an implementation in JavaScript that performs the conversion for each of those 4-noded trees, and pretty prints the resulting trees:
function makeBinaryTree(input) {
let i = 0; // character index in input
return recur();
function recur() {
if (i >= input.length || input[i++] === ")") return null;
let node = { left: recur(), right: null };
if (i >= input.length || input[i] === ")") {
i++;
return node;
}
node.right = recur();
return node;
}
}
// Helper function to pretty print a tree
const disc = "\u2B24";
function treeAsLines(node) {
let left = [""], right = [""];
if (node.left) left = treeAsLines(node.left);
if (node.right) right = treeAsLines(node.right);
while (left.length < right.length) left.push(" ".repeat(left[0].length));
while (left.length > right.length) right.push(" ".repeat(left[0].length));
let topLeft = "", topRight = "";
let i = left[0].indexOf(disc);
if (i > -1) topLeft = "┌".padEnd(left[0].length-i+1, "─");
i = right[0].indexOf(disc);
if (i > -1) topRight = "┐".padStart(i+2, "─");
return [topLeft.padStart(left[0].length+1) + disc + topRight.padEnd(right[0].length+1)]
.concat(left.map((line, i) => line + " " + right[i]));
}
// The trees as listed in Table 1 of http://www.cs.utsa.edu/~wagner/knuth/fasc4a.pdf
let inputs = [
"()()()()",
"()()(())",
"()(())()",
"()(()())",
"()((()))",
"(())()()",
"(())(())",
"(()())()",
"(()()())",
"(()(()))",
"((()))()",
"((())())",
"((()()))",
"(((())))"
];
for (let input of inputs) {
let tree = makeBinaryTree(input);
console.log(input);
console.log(treeAsLines(tree).join("\n"));
}
If I understood Knuth correctly, the representation works as the following: A pair of matching parentheses represents a node, e.g. () = A. Two consecutive pairs of matching parentheses means that the second node is the right child of the first one, e.g. ()() = A -> B. And two pairs of embedded parentheses means the inside node is the left child of the outside node, i.e. (()) = B <- A. Therefore, ()()()() = A -> B -> C -> D.
A possible algorithm to convert parentheses to binary tree would be:
convert(parentheses):
if parentheses is empty:
return Nil
root = Node()
left_start = 1
left_end = Nil
open = 0
for p = 0 to |parentheses|-1:
if parentheses[p] == '(':
open += 1
else
open -= 1
if open == 0:
left_end = p
break
root.left = convert(parentheses[left_start:left_end] or empty if index out of bound)
root.right = convert(parentheses[left_end+1:] or empty if index out of bound)
return root
It works by converting parentheses (L)R in the binary tree L <- A -> R recursively.

How to check if a binary tree is a valid BST if it contains duplicates or contains +/- infinity?

My solution to check if binary tree is a BST is as follow:
def is_BST(node):
if node is None:
return False
stack = [(node, -float('inf'), float('inf')]
while len(stack) > 0:
node, lb, ub = stack.pop()
if node.val <= lb or node.val >= ub:
return False
if node.left:
stack.append((node.left, lb, node.val))
if node.right:
stack.append((node.right, node.val, ub))
return True
But if the tree contains -inf or inf, or has duplicate values, my function won't work properly. How can I adjust it so that it works more generally?
You can implement a recursive function that is more elegant, also using set:
set = {-float('inf'), float('inf')}
isValid = True
def BST(node):
if(node is None):
return
if node.value in set:
global isValid
isValid = False
else:
set.add(node.value)
BST(node.left)
BST(node.right)
Your code doesn't seem to work well:
node, lb, ub = stack.pop()
Here you are removing your nodes, you have to keep all the data for finding duplicates.

Maximum element in a tree

I have the following ADT implementation in Scala.
How to find the maximum element in the tree? Can I introduce some helper function, and if yes, then how?
abstract class MySet {
def max: Int
def contains(tweet: Tweet): Boolean = false
}
class Empty extends MySet {
def max: throw new NoSuchElementExeption("max called on empty tree")
def contains(x: Int): Boolean =
if (x < elem) left.contains(x)
else if (elem < x) right.contains(x)
else true
}
class Node(elem: Int, left: MySet, right: MySet) extends Set {
def max: { ... }
def contains(x: Int): Boolean =
if (x < elem) left.contains(x)
else if (elem < x) right.contains(x)
else true
}
I found a solution in Haskell which feels quite intuitive can I convert it to Scala somehow?
data Tree a = Nil | Node a (Tree a) (Tree a)
maxElement Nil = error "maxElement called on empty tree"
maxElement (Node x Nil Nil) = x
maxElement (Node x Nil r) = max x (maxElement r)
maxElement (Node x l Nil) = max x (maxElement l)
maxElement (Node x l r) = maximum [x, maxElement l, maxElement r]
Update
I am not interested in copying the Haskell code in Scala instead I think Haskell version is more intuitive but because of this keyword and other stuff in Object oriented language. How can I write the equivalent code in object oriented style without pattern matching?
Your tree is heterogeneous, which means that each node can be either a full node with a value, or an empty leaf. Hence you need to distinguish which is which, otherwise you can call max on an empty node. There are many ways:
Classic OOP:
abstract class MySet {
def isEmpty: Boolean
...
}
class Empty extends MySet {
def isEmpty = true
...
}
class Node(...) extends MySet {
def isEmpty = false
...
}
So you do something like this:
var maxElem = elem
if(!left.isEmpty)
maxElem = maxElem.max(left.max)
end
if(!right.isEmpty)
maxElem = maxElem.max(right.max)
end
Since JVM has class information at runtime you can skip the definition of isEmpty:
var maxElem = elem
if(left.isInstanceOf[Node])
maxElem = maxElem.max(left.asInstanceOf[Node].max)
end
if(left.isInstanceOf[Node])
maxElem = maxElem.max(right.asInstanceOf[Node].max)
end
(asInstanceOf is not required if you defined max in MySet, but this pattern covers the case when you didn't)
Well, Scala has a syntactic sugar for the latter, and not surprisingly it's the pattern matching:
var maxElem = elem
left match {
case node: Node =>
maxElem = maxElem.max(node.max)
case _ =>
}
right match {
case node: Node =>
maxElem = maxElem.max(node.max)
case _ =>
}
maxElem
You can take it slightly further and write something like this:
def max = (left, right) match {
case (_: Empty, _: Empty) => elem
case (_: Empty, node: Node) => elem.max(node.max)
case (node: Node, _: Empty) => elem.max(node.max)
case (leftNode: Node, rightNode: Node) =>
elem.max(leftNode.max).max(rightNode.max)
}
If you don't want to use pattern matching, you will need to implement an isEmpty operation or its equivalent, to avoid calling max on an empty set.
The important thing is how the tree is organized. Based on the implementation of contains, it looks like you have an ordered tree (a "binary search tree") where every element in the left part is less than or equal to every element in the right part. If that's the case, your problem is fairly simple. Either the right sub tree is empty and the current element is the max, or the max element of the tree is the max of the right sub tree. That should be a simple recursive implementation with nothing fancy required.
Full disclosure, still learning Scala myself, but here is two versions I came up with (which the pattern match looks like a fair translation of the Haskell code)
sealed trait Tree {
def max: Int
def maxMatch: Int
}
case object EmptyTree extends Tree {
def max = 0
def maxMatch = 0
}
case class Node(data:Int,
left:Tree = EmptyTree,
right:Tree = EmptyTree) extends Tree {
def max:Int = {
data
.max(left.max)
.max(right.max)
}
def maxMatch: Int = {
this match {
case Node(x,EmptyTree,EmptyTree) => x
case Node(x,l:Node,EmptyTree) => x max l.maxMatch
case Node(x,EmptyTree,r:Node) => x max r.maxMatch
case Node(x,l:Node,r:Node) => x max (l.maxMatch max r.maxMatch)
}
}
}
Tests (all passing)
val simpleNode = Node(3)
assert(simpleNode.max == 3)
assert(simpleNode.maxMatch == 3)
val leftLeaf = Node(1, Node(5))
assert(leftLeaf.max == 5)
assert(leftLeaf.maxMatch == 5)
val leftLeafMaxRoot = Node(5,
EmptyTree, Node(2))
assert(leftLeafMaxRoot.max == 5)
assert(leftLeafMaxRoot.maxMatch == 5)
val nestedRightTree = Node(1,
EmptyTree,
Node(2,
EmptyTree, Node(3)))
assert(nestedRightTree.max == 3)
assert(nestedRightTree.maxMatch == 3)
val partialFullTree = Node(1,
Node(2,
Node(4)),
Node(3,
Node(6, Node(7))))
assert(partialFullTree.max == 7)
assert(partialFullTree.maxMatch == 7)

What does stack[-1] mean in a pseudocode?

def _all_simple_paths_graph(G, source, target, cutoff=None):
if cutoff < 1:
return
visited = [source]
stack = [iter(G[source])]
while stack:
children = stack[-1]
child = next(children, None)
if child is None:
stack.pop()
visited.pop()
elif len(visited) < cutoff:
if child == target:
yield visited + [target]
elif child not in visited:
visited.append(child)
stack.append(iter(G[child]))
else: #len(visited) == cutoff:
if child == target or target in children:
yield visited + [target]
stack.pop()
visited.pop()
I find that code on this link.
But did not understand some statements, as following
children = stack[-1] // What does stack[-1] mean?
child = next(children, None) // Is child a list or children is a list?
stack = [iter(G[source])] // What is that iter?
if child is None: // Guess if child is empty (child is a list).
visited = [source] // What is that?
yield visited + [target] // Yield?
Can anyone explain to me? I am trying to rewrite it in C.
It looks like a python code
1)
stack[-1] means it will give the last element.
2)
children is a variable, which by this code holds the last element of the list stack
children = stack[-1]
child is whatever next() function returns, but by the looks of it, it also looks like a variable.
4)
if child is None:
if the next() function returns None

How do I improve the algorithm for my Traffic Jam recursive solver?

Theres a cute little game on Android called Traffic Jam
I've written a recursive solver:
import copy,sys
sys.setrecursionlimit(10000)
def lookup_car(car_string,ingrid):
car=[]
i=0
for row in ingrid:
j=0
for cell in row:
if cell == car_string:
car.append([i,j])
j+=1
i+=1
return car
#True if up/down False if side to side
def isDirectionUp(car):
init_row=car[0][0]
for node in car:
if node[0] != init_row:
return True
return False
def space_up(car,grid):
top_node=car[0]
m_space_up = (top_node[0]-1,top_node[1])
if top_node[0] == 0:
return -1
elif grid[m_space_up[0]][m_space_up[1]] != " ":
return -1
else:
return m_space_up
def space_down(car,grid):
bottom_node = car[-1]
m_space_down = (bottom_node[0]+1,bottom_node[1])
if bottom_node[0] == 5 :
return -1
elif grid[m_space_down[0]][m_space_down[1]] != " ":
return -1
else:
return m_space_down
def space_left(car,grid):
left_node = car[0]
m_space_left = (left_node[0],left_node[1]-1)
if left_node[1] == 0 :
return -1
elif grid[m_space_left[0]][m_space_left[1]] != " ":
return -1
else:
return m_space_left
def space_right(car,grid):
right_node = car[-1]
m_space_right = (right_node[0],right_node[1]+1)
if right_node[1] == 5 :
return -1
elif grid[m_space_right[0]][m_space_right[1]] != " ":
return -1
else:
return m_space_right
def list_moves(car,grid):
ret =[]
if isDirectionUp(car):
up = space_up(car,grid)
if up != -1:
ret.append(("UP",up))
down = space_down(car,grid)
if down != -1:
ret.append(("DOWN",down))
else:
left = space_left(car,grid)
if left != -1:
ret.append(("LEFT",left))
right = space_right(car,grid)
if right != -1:
ret.append(("RIGHT",right))
return ret
def move_car(car_string,move,ingrid):
grid = copy.deepcopy(ingrid)
car = lookup_car(car_string,grid)
move_to = move[1]
front = car[0]
back = car[-1]
if(move[0] == "UP" or move[0] == "LEFT"):
grid[back[0]][back[1]] = " "
grid[move_to[0]][move_to[1]] = car_string
elif(move[0] == "DOWN" or move[0] == "RIGHT"):
grid[front[0]][front[1]] = " "
grid[move_to[0]][move_to[1]] = car_string
return grid
def is_solution(grid):
car = lookup_car("z",grid)
if(car[-1] == [2,5]):
return True
elif space_right(car,grid) == -1:
return False
else:
solgrid = move_car("z",("RIGHT",space_right(car,grid)),grid)
return is_solution(solgrid)
def print_grid(grid):
for row in grid:
print ''.join(row)
def solve(grid,solution,depth):
global stop
global state
if grid in state:
return
else:
state.append(grid)
if stop:
return
if is_solution(grid):
print_grid(grid)
print len(solution)
else:
for each in "abcdefzhijklm":
car = lookup_car(each,grid)
moves = list_moves(car,grid)
for move in moves:
solution.append((each,move))
moved_grid = move_car(each,move,grid)
solve(moved_grid,solution,depth)
stop=False
state=[]
recdepth=0
#grid file using a-w and x means free space, and ' ' means yellow car
grid=[list(x) for x in file(sys.argv[1]).read().split('\n')[0:-1]]
solve(grid,[],0)
WHERE grid is in a file:
abccdd
abeef
azzhfi
jjjhfi
kll
kmm
But, it takes over 8000 moves to find a solution ,and fails to find a simple 30 move solution. What is wrong with the algorithm?
If the branching factor of your search space is r then the number of vertices in the search tree to depth n is (1-r^n)/(1-r). A problem with a minimal 30 step solution, even in the simple case where r = 2, will have a search tree with around 2^30 - 1 ~= 1,000,000,000 vertices. Now, your branching factor is likely to be bigger than 2, so a 30 step problem is a long way from trivial!
That said, I'd be inclined to (a) find a better representation of your problem (searching arrays of strings is slow) and (b) consider best-first search where you guide your search with a heuristic (e.g., distance of the yellow car from its destination or the number of cars blocking the path of the yellow car).
Hope this helps.
This is essentially a (relatively token) searching problem, with a huge search space. As others recommended, read up on Depth-first search, and then read up on Breadth-first search, and when you learn the difference, read up on A* Search, and coming up with a pessimistic scoring function.
Also, note that in this case, you already know what the end state should be, thus, another approach would be to search from both ends and meet in the middle. This should reduce your search space considerably.
If that's still not enough, you can combine the techniques!

Resources