diff --git a/kth_smallest_element_in_a_bst_230/README.md b/kth_smallest_element_in_a_bst_230/README.md new file mode 100644 index 0000000..39bc913 --- /dev/null +++ b/kth_smallest_element_in_a_bst_230/README.md @@ -0,0 +1,42 @@ +# 230. Kth Smallest Element in a BST + +https://leetcode.com/problems/kth-smallest-element-in-a-bst/ + +## Difficulty: + +Medium + +## Description + +Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. + +Note: +You may assume k is always valid, `1 ≤ k ≤ BST's` total elements. + +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? diff --git a/kth_smallest_element_in_a_bst_230/solution.go b/kth_smallest_element_in_a_bst_230/solution.go new file mode 100644 index 0000000..71843d3 --- /dev/null +++ b/kth_smallest_element_in_a_bst_230/solution.go @@ -0,0 +1,33 @@ +package kth_smallest_element_in_a_bst_230 + +import ( + . "github.com/austingebauer/go-leetcode/structures" + "math" +) + +func kthSmallest(root *TreeNode, k int) int { + _, v := inOrderTraverse(root, k) + return v +} + +func inOrderTraverse(root *TreeNode, k int) (int, int) { + if root == nil { + return k, math.MaxInt32 + } + + var val int + k, val = inOrderTraverse(root.Left, k) + + // Stop traverse when the kth smallest number has been found + if val != math.MaxInt32 { + return k, val + } + + // When k becomes zero, the kth smallest number has been found + k-- + if k == 0 { + return k, root.Val + } + + return inOrderTraverse(root.Right, k) +} diff --git a/kth_smallest_element_in_a_bst_230/solution_test.go b/kth_smallest_element_in_a_bst_230/solution_test.go new file mode 100644 index 0000000..93690d3 --- /dev/null +++ b/kth_smallest_element_in_a_bst_230/solution_test.go @@ -0,0 +1,94 @@ +package kth_smallest_element_in_a_bst_230 + +import ( + . "github.com/austingebauer/go-leetcode/structures" + "github.com/stretchr/testify/assert" + "testing" +) + +func Test_kthSmallest(t *testing.T) { + type args struct { + root *TreeNode + k int + } + tests := []struct { + name string + args args + want int + }{ + { + name: "Kth Smallest Element in a BST", + args: args{ + root: &TreeNode{ + Val: 3, + Left: &TreeNode{ + Val: 1, + Right: &TreeNode{ + Val: 2, + }, + }, + Right: &TreeNode{ + Val: 4, + }, + }, + k: 1, + }, + want: 1, + }, + { + name: "Kth Smallest Element in a BST", + args: args{ + root: &TreeNode{ + Val: 5, + Left: &TreeNode{ + Val: 3, + Right: &TreeNode{ + Val: 4, + }, + Left: &TreeNode{ + Val: 2, + Left: &TreeNode{ + Val: 1, + }, + }, + }, + Right: &TreeNode{ + Val: 6, + }, + }, + k: 3, + }, + want: 3, + }, + { + name: "Kth Smallest Element in a BST", + args: args{ + root: &TreeNode{ + Val: 5, + Left: &TreeNode{ + Val: 3, + Right: &TreeNode{ + Val: 4, + }, + Left: &TreeNode{ + Val: 2, + Left: &TreeNode{ + Val: 1, + }, + }, + }, + Right: &TreeNode{ + Val: 6, + }, + }, + k: 4, + }, + want: 4, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, kthSmallest(tt.args.root, tt.args.k)) + }) + } +}