Iterative inorder, counting as you go:
def kthSmallest(root, k):
stack = []
current = root
while True:
while current:
stack.append(current)
current = current.left
current = stack.pop()
k -= 1
if k == 0:
return current.val
current = current.right
Time: . You descend to the leftmost node (), then visit nodes. Space: for the stack.
For the follow-up: augment each node with the size of its left subtree. Then you can find the kth smallest in time by comparing with subtree sizes.