casyup.me@outlook.com

0%

leetcode/230KthSmallestElementInaBST

Kth Smallest Element In a BST

找到二叉树中, 第 n 个最小的节点

my solution

可以一步一步找它的最小节点, 追踪的问题, 可以交给 stack

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
func kthSmallest(root *TreeNode, k int) int {
// if root == nil {
// return 0
// }
stack := []*TreeNode{root}

for root.Left != nil {
stack = append(stack, root.Left)
root = root.Left
}

pos := len(stack) - 1

for foot := 1; foot != k; foot++ {
// if cur.Right != nil then next is cur.Right.Left(bottom)
if stack[pos].Right != nil {
// i really need stack...
if len(stack) > pos + 1 {
stack[pos + 1] = stack[pos].Right
} else {
stack = append(stack, stack[pos].Right)
}
pos++

for stack[pos].Left != nil {
if len(stack) > pos + 1 {
stack[pos + 1] = stack[pos].Left
} else {
stack = append(stack, stack[pos].Left)
}
pos++
}
} else {
// if cur.Right == nil then next is last biger value
old := stack[pos].Val

// hope BST don't have repetitive value...
for stack[pos].Val <= old {
pos--
}
}
}

return stack[pos].Val
}

查找下一节点 (next) 可以这么描述:

如果当前节点 (cur) 有右子节点, 则 next 为右子节点的左根节点

否则, next 为上一个大于当前节点值的节点

这是用递归来实现的, 为了追踪, 使用了 stack

(我好希望 go 能提供一个标准的 stack, 这样代码可以更加简洁. 或许是提供了, 但我不知道?)

一次成功, 真好

the best solution

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
func kthSmallest(root *TreeNode, k int) int {
res = 0
helper(root,k,1)
return res
}
var res int

func helper(root *TreeNode, k int, i int) int {
cur := 0
if root.Left != nil {
prev := helper(root.Left, k, i)
cur = prev + 1
} else {
cur = i
}

if cur == k {
res = root.Val
}

if root.Right != nil && cur < k {
return helper(root.Right, k, cur+1)
}
return cur
}

emm, 他使用了递归, 用递归来追踪, 可以不用显式追踪数据了, 挺好