题目链接: 二叉搜索树中第 K 小的元素
二叉搜索树的性质
- 左子树性质
任意节点的左子树中所有节点的值 都小于 该节点的值。
- 右子树性质
任意节点的右子树中所有节点的值 都大于 该节点的值。
- 递归性
左子树和右子树本身也必须是二叉搜索树(即递归满足以上两条性质)。
- 没有重复节点(通常情况)
标准的 BST 通常假设节点值唯一(不包含相等的值)。若有重复值,可以约定放在左子树或右子树(实践中常扩展定义)。
- 中序遍历是有序序列
对 BST 进行中序遍历(左 → 根 → 右),得到的结果是一个 严格递增 的序列。这是 BST 最重要的一个实用性质。
思路
本题主要考察第五个性质, 中序遍历二叉树,并计数,即可得到第k小的节点值.
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public int cnt=0; public int ans=-1; public int kthSmallest(TreeNode root, int k) { inorder(root,k); return ans; } public void inorder(TreeNode root,int k) { if(root==null||ans!=-1) return ; inorder(root.left,k); cnt++; if(cnt==k) { ans=root.val; return; } inorder(root.right,k); } }
|
易错
刚写的时候写错了,找不出自己错哪里了,原来我把cnt当做函数形参传递了(初始为0),其他没变化.
为啥这样不对?
因为java只有值传递, 每一次进入递归函数 对cnt++的操作只会在当前栈帧有效, 对其他栈帧的cnt没影响..
模拟一下,当初次进入递归函数, cnt=0,会一直向左子树递归,然后就导致一路上的cnt都是0, 就导致返回的时候,cnt变化了, 但是那一路上的cnt还都是0. 就导致错误了 。
下面是另一个版本(ai):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public int kthSmallest(TreeNode root, int k) { return inorder(root, new int[]{k}); } private int inorder(TreeNode root, int[] k) { if (root == null) return -1; int leftResult = inorder(root.left, k); if (k[0] == 0) return leftResult; k[0]--; if (k[0] == 0) return root.val; return inorder(root.right, k); } }
|
__END__