java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 |
---|
1. 中序遍历
解题思路:时间复杂度O(H+k)其中H是树高,k是要找第几个结点。空间复杂度O(H) |
---|
- 二叉搜索树,中序遍历序列就是升序排列。比如上面示例1的中序遍历结果为1,2,3,4,正好是升序序列
- 所以我们只需要进行中序遍历的过程中记录当前是第几个结点,如果是第k个,直接返回即可。
- 递归法
class Solution {int ans;int th=0;public int kthSmallest(TreeNode root, int k) {ans = root.val;dfs(root,k);return ans;}public void dfs(TreeNode root , int k){if(root == null) return;if(th>=k)return;dfs(root.left,k);if(++th == k) ans = root.val;dfs(root.right,k);}
}
- 迭代法
class Solution {public int kthSmallest(TreeNode root, int k) {Deque<TreeNode> stack = new ArrayDeque<TreeNode>();while (root != null || !stack.isEmpty()) {while (root != null) {stack.push(root);root = root.left;}root = stack.pop();if (--k == 0) break;root = root.right;}return root.val;}
}
2. 预处理
如果需要频繁进行查找第k个元素的操作,就不能每次都进行中序遍历,太费时间了,平均时间复杂度会很高
所以我们记录每个结点的左子结点个数,和右子结点个数
- 当前node.left的结点个数<k-1,则第k小元素在node.right. 此时去右边只需找第k - left - 1个元素即可
- node.left结点个数 = k-1,则第k小元素为node,返回node即可
- node.left结点个数 > k-1,则第k小元素在node.left,令node = node.left继续搜索即可
代码:此算法做题肯定慢,但是实战中,仅仅是第一次预处理时会慢,之后再查的时候就会很快了 |
---|
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);}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;}private int countNodeNum(TreeNode node) {if (node == null) {return 0;}nodeNum.put(node, 1 + countNodeNum(node.left) + countNodeNum(node.right));return nodeNum.get(node);}private int getNodeNum(TreeNode node) {return nodeNum.getOrDefault(node, 0);}
}