题解:
二叉搜索树中序遍历的结果,是升序数组, 所以先中序遍历数组,第k个元素即为第k个小的元素。
思路一:
迭代 代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
List<Integer> list = new ArrayList<>();
List<Integer> dfs (TreeNode root){
if (root == null) return list;
dfs(root.left);
list.add(root.val);
dfs(root.right);
return list;
}
public int kthSmallest(TreeNode root, int k) {
// 获取数组
dfs(root);
return list.get(k);
}
|
思路二:
递归 代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
List<Integer> dfs1(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
list.add(root.val);
root = root.right;
}
return list;
}
public int kthSmallest(TreeNode root, int k) {
// 获取数组
List<Integer> list = dfs1(root);
return list.get(k);
}
|
上述两种方法中, 时间复杂度都是 O(N) ,遍历了树的所有节点。
空间复杂度也是 O(N), 用到了额外的存储N个元素的数组。
优化:
上述解题,我们看出,我们完全不需要遍历整个二叉树,中序遍历到第K位就能求出结果,完全没必要继续遍历。 所有下边我们优化
思路三:
优化时间复杂度至 O(K), 空间复杂度至 O(1)
迭代
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 优化遍历次数 且不需要额外数组存储
public int dfs(TreeNode root, int k){
Stack<TreeNode> stack = new Stack<>();
int count = 0;
while (!stack.isEmpty() || root != null){
while (root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
count ++;
if (count == k) return root.val;
root = root.right;
}
return -1;
}
|
思路四:
优化时间复杂度至 O(K), 空间复杂度至 O(1)
递归 代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
int count = 0;
int res;
public void dfs(TreeNode root,int k){
if (root == null) return;
dfs(root.left, k);
count ++;
if (k == count) {
res = root.val;
}
dfs(root.right, k);
}
public int kthSmallest(TreeNode root, int k) {
dfs(root,k);
return res;
}
|