"""230. Kth Smallest Element in a BST
https://leetcode.com/problems/kth-smallest-element-in-a-bst/

Given a binary search tree, write a function kthSmallest to
find the kth smallest element in it.

Example 1:

Input: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
Output: 1
Example 2:

Input: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / \
     3   6
    / \
   2   4
  /
 1
Output: 3

Follow up:
What if the BST is modified (insert/delete operations) often and
you need to find the kth smallest frequently?
How would you optimize the kthSmallest routine?

Constraints:

The number of elements of the BST is between 1 to 10^4.
You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
"""
from common.tree_node import TreeNode


class Solution:
    def kth_smallest(self, root: TreeNode, k: int) -> int:
        def enqueue(node: TreeNode):
            while node:
                stack.append(node)
                node = node.left
        stack = []
        ptr = root
        enqueue(ptr)
        count = 0
        while stack:
            node = stack.pop(-1)
            count += 1
            if count == k:
                return node.val
            if node.right:
                enqueue(node.right)

"""230. Kth Smallest Element in a BST
https://leetcode.com/problems/kth-smallest-element-in-a-bst/

Given a binary search tree, write a function kthSmallest to
find the kth smallest element in it.

Example 1:

Input: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
Output: 1
Example 2:

Input: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / \
     3   6
    / \
   2   4
  /
 1
Output: 3

Follow up:
What if the BST is modified (insert/delete operations) often and
you need to find the kth smallest frequently?
How would you optimize the kthSmallest routine?

Constraints:

The number of elements of the BST is between 1 to 10^4.
You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
"""
from common.tree_node import TreeNode


class Solution:
    def kth_smallest(self, root: TreeNode, k: int) -> int:
        def enqueue(node: TreeNode):
            while node:
                stack.append(node)
                node = node.left
        stack = []
        ptr = root
        enqueue(ptr)
        count = 0
        while stack:
            node = stack.pop(-1)
            count += 1
            if count == k:
                return node.val
            if node.right:
                enqueue(node.right)

230. Kth Smallest Element in a BST https://leetcode.com/problems/kth-smallest-element-in-a-bst/  Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.  Example 1:  Input: root = [3,1,4,null,2], k = 1    3   / \  1   4   \    2 Output: 1 Example 2:  Input: root = [5,3,6,2,4,null,null,1], k = 3        5       / \      3   6     / \    2   4   /  1 Output: 3  Follow up: What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?  Constraints:  The number of elements of the BST is between 1 to 10^4. You may assume k is always valid, 1 ≤ k ≤ BST's total elements.