每日三刷,剑指千题
计划简介:
- 每日三题,以中等题为主,简单题为辅进行搭配。保证质量题1道,数量题3道。
- 每日早通勤在LeetCode手机端选题,思考思路,没答案的直接看题解。
- 每日中午进行编码,时间控制在一小时之内。
- 下班前半小时进行整理总结,并发布到掘金每日更文活动。
说明:
- 基于以前的刷题基础,本次计划以中等题为主,大部分中等题都可以拆分为多个简单题,所以数量保证3,质量保证一道中等题即可。
- 刷题顺序按照先刷链表、二叉树、栈、堆、队列等基本数据结构,再刷递归、二分法、排序、双指针等基础算法,最后是动态规划、贪心、回溯、搜索等复杂算法。
- 刷题过程中整理相似题型,刷题模板。
- 目前进度 136/1000 。
[230]二叉搜索树中第K小的元素
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。
示例 1:
输入:root = [3,1,4,null,2], k = 1
输出:1
解析
第一遍没想明白index++的位置,缕了一遍之后更深刻的理解了深度优先搜索。
Code
class Solution {
int ans = 0;
int index = 1;
public int kthSmallest(TreeNode root, int k) {
dfs(root,k);
return ans;
}
void dfs(TreeNode root,int k){
if (root == null)return;
dfs(root.left,k);
if (index == k){
ans = root.val;
}
index++;
dfs(root.right,k);
}
}
[783]二叉搜索树节点最小距离
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
输入:root = [4,2,6,1,3]
输出:1
注意: 本题与 530:leetcode-cn.com/problems/mi… 相同
解析
首先要明白一个问题是,对于二叉搜索树,采用中序遍历即从小到大排序,那遍历完之后的最小值只可能出现在相邻的两个元素。
所以思路就是先遍历得到排好序的列表,相邻元素相减,再比较最小值。
这样可以通过但效率不高,需要边遍历,边比较。
Code
class Solution {
Stack<Integer> temp = new Stack();
int ans = 9999999;
public int minDiffInBST(TreeNode root) {
temp.push(-9999999);
dfs(root);
return ans;
}
void dfs(TreeNode root){
if (root == null)return;
dfs(root.left);
ans = Math.min(ans,root.val-temp.pop());
temp.push(root.val);
dfs(root.right);
}
}
[863]二叉树中所有距离为 K 的结点
给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 k 。
返回到目标结点 target 距离为 k 的所有结点的值的列表。 答案可以以 任何顺序 返回。
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2
输出:[7,4,1]
解释:所求结点为与目标结点(值为 5)距离为 2 的结点,值分别为 7,4,以及 1
解析
从给的案例可以看出,5到7,4是比较容易的,5到3的就不太容易了。
那如何把目标节点看作根节点呢?
先找出root和目标节点的距离吗?
那就应该还是层序遍历。
搞了半天,发现不行,看完官方的题解,还是不懂,稍后慢慢消化吧。
Code
class Solution {
Map<Integer, TreeNode> parents = new HashMap<Integer, TreeNode>();
List<Integer> ans = new ArrayList<Integer>();
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
// 从 root 出发 DFS,记录每个结点的父结点
findParents(root);
// 从 target 出发 DFS,寻找所有深度为 k 的结点
findAns(target, null, 0, k);
return ans;
}
public void findParents(TreeNode node) {
if (node.left != null) {
parents.put(node.left.val, node);
findParents(node.left);
}
if (node.right != null) {
parents.put(node.right.val, node);
findParents(node.right);
}
}
public void findAns(TreeNode node, TreeNode from, int depth, int k) {
if (node == null) {
return;
}
if (depth == k) {
ans.add(node.val);
return;
}
if (node.left != from) {
findAns(node.left, node, depth + 1, k);
}
if (node.right != from) {
findAns(node.right, node, depth + 1, k);
}
if (parents.get(node.val) != from) {
findAns(parents.get(node.val), node, depth + 1, k);
}
}
}
\