Kth largest value of binary search tree
The following problem helped me understand that in-order traversal of a binary search tree yields a sorted array.
     
Problem statement
Write a function that takes in a Binary Search Tree(BST) and a positive integer k and returns the kth largest integer contained in the BST
Assume the following:
- there will only be integer values in the BST
- k <= number of nodes in the BST
- if tree = [5, 7, 7] second largest value of the BST will be 7 and not 5
Understand
Input: [15, 5, 20, 2, 5, 17, 22, 1, 3],k = 3
Output: 17

Explanation: after 22 and 20, 17 is the largest values in the given BST
Input: [1], k=1
Output: 1
Input: [1], k=2
Output: not a valid case
Input: [2,1,3], k=3
Output: 3
Input: [1,null,2,null,3,null,4], k=0
Output: Not a valid case
Match
List
// traverse tree 
    build node_list 
// sort nodes_list in descending order
// return node_list[k]
- complexity:
    - time: O(n)+O(n log n) -> O(n log n)
- space: O(n)
 
Linked list
- using linked list will cost us extra time to create a liked list
Hashmap asd Hashset
- both the data structure are not useful for solving the problem
Stack and Queue
- we are not required to look for or maintain LIFO or FIFO order
Heap
- Heap are very helpful to find the kth largest or kth smallest elements
    // create max heap // pop k times // return kth popped item
- complexity:
    - time: O(n) + O(n log n) -> O(n log n)
- space: O(n)
 
- all though with heap we can obtain the kth element, it did not improve the complexity of the algorithm that we came up by using list
Techniques
- we can traverse a tree using BFS or DFS
- DFS has preorder, postorder and inorder traversal
Exploring the traversals
- let us consider out first example, tree = [15,5,20,2,5,17,22,1,3] and check the order of the nodes that we visit with each traversal
Breadth first search
- bfs traversal of BST = [[1],[2,3],[5,5,15,17],[20,22]]
Preorder traversal
- preorder traversal of BST = [15,5,20,2,5,17,22,1,3] is [15,5,2,1,3,5,20,17,22]
Postorder traversal
- postorder traversal of BST = [15,5,20,2,5,17,22,1,3] is [1,3,2,5,5,17,22,20,15]
Inorder traversal
- 
    inorder traversal of BST = [15,5,20,2,5,17,22,1,3] is [1,2,3,5,5,15,17,20,22] 
- comparing all the traversals it is safe to conclude that in-order traversal yields a sorted array
- taking advantage of this property we can arrive at the solution arrive at the solution
- high level steps involved are
    - traverse tree in inorder fashion - build array of nodes
- return array[len(array)-k]
 
// dfs - inorder recursive 
// list of nodes
// return kth element from end
- complexity:
    - time: O(n)
- space: O(n)+O(n) -> O(n)
 
- we could traverse the tree in reverse in-order to get the list of values in descending order
- we can do so by adding left child on to the stack an then the right child so the right child is processed before the left child
// reverse in-order -> recursion
// list of nodes 
// return kth element 
- complexity:
    - time: O(n)
- space: O(n)+O(n)
 
Implementation
class BST:
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right
def reverse_inorder(root, array, k):
	if root == None:
		return None
	node = root
	stack = [node]
	while stack:
		if node == None:
			node = stack.pop() 
			array.append(node.value) 
			node = node.left
		else:
			stack.append(node)
			node = node.right
	
def findKthLargestValueInBst(tree, k):
	if tree == None:
		return None
	nodes_list = []
	reverse_inorder(tree, nodes_list, k)
    return nodes_list[k-1]
Review
- for the input tree [15, 5, 20, 2, 5, 17, 22, 1, 3] and k = 3
    - nodes_list = [22, 20, 17, 15, 5, 5, 3, 2, 1, 15]
 
Evaluate:
- complexity:
    - traverse tree -> time: O(n)
- nodes_list + call stack -> space: O(n)+O(n)