230 寻找二叉查找树的第 k 个元素
寻找二叉查找树的第 k 个元素
-
解法一
利用中序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
private int count = 0; public int kthSmallest(TreeNode root, int k) { ArrayDeque<TreeNode> stack = new ArrayDeque<>(); TreeNode cur = root; while (cur != null || !stack.isEmpty()) { if (cur != null) { stack.push(cur); cur = cur.left; } else { TreeNode node = stack.pop(); if (++count == k) { return node.val; } cur = node.right; } } return -1; }
-
解法二
如果你需要频繁地查找第 k 小的值,你将如何优化算法?
利用hashmap为每个节点存以该节点为 root 的子树的节点个数。
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 46 47
class Solution { public int kthSmallest(TreeNode root, int k) { MyBst bst = new MyBst(root); return bst.kthSmallest(k); } } class MyBst { TreeNode root; Map<TreeNode, Integer> nodeNum; public MyBst(TreeNode root) { this.root = root; this.nodeNum = new HashMap<TreeNode, Integer>(); countNodeNum(root); } // 返回二叉搜索树中第k小的元素 public int kthSmallest(int k) { TreeNode node = root; while (node != null) { int left = getNodeNum(node.left); if (left < k - 1) { node = node.right; k -= left + 1; } else if (left == k - 1) { break; } else { node = node.left; } } return node.val; } // 统计以node为根结点的子树的结点数 private int countNodeNum(TreeNode node) { if (node == null) { return 0; } nodeNum.put(node, 1 + countNodeNum(node.left) + countNodeNum(node.right)); return nodeNum.get(node); } // 获取以node为根结点的子树的结点数 private int getNodeNum(TreeNode node) { return nodeNum.getOrDefault(node, 0); }
Read other posts