Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
一、前言
刷题啊!!!
开始刷 “剑指 Offer” 31天。刷完时间:2022.3.6 ~ 2022.3.20。
二、题目
题目:
- 二叉树中和为某一值的路径
- 二叉搜索树与双向链表
- 二叉搜索树的第k大节点
(1)剑指 Offer 34. 二叉树中和为某一值的路径
题目描述
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
题解
注意:要从根节点到子节点,才算完整的链路。
思路:
- 遍历节点的左右子树
- 更新
target - 添加到结果
AC 代码如下:
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int target) {
if (null == root) return Collections.emptyList();
List<List<Integer>> result = new ArrayList<>();
findPath(result, root, Collections.emptyList(), target);
return result;
}
private void findPath(List<List<Integer>> result, TreeNode root, List<Integer> list, int target) {
if (null == root) return;
if (root.val == target && null == root.left && null == root.right) {
List<Integer> subList = new ArrayList<>(list);
subList.add(root.val);
result.add(subList);
return;
}
List<Integer> tmpList = new ArrayList<>(list);
tmpList.add(root.val);
findPath(result, root.left, tmpList, target - root.val);
tmpList = new ArrayList<>(list);
tmpList.add(root.val);
findPath(result, root.right, tmpList, target - root.val);
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
(2)剑指 Offer 36. 二叉搜索树与双向链表
题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
题解
AC 代码如下:
class Solution {
public Node treeToDoublyList(Node root) {
if (null == root) return null;
Node dummy = new Node(0);
LinkedList<Node> list = new LinkedList<>();
travel(list, root);
Node cur = dummy;
for (Node node : list) {
cur.right = node;
node.left = cur;
cur = node;
}
Node head = list.peekFirst();
Node tail = list.peekLast();
head.left = tail;
tail.right = head;
return head;
}
private void travel(LinkedList<Node> list, Node root) {
if (null == root) return ;
travel(list, root.left);
list.add(new Node(root.val));
travel(list, root.right);
}
}
(3)剑指 Offer 54. 二叉搜索树的第k大节点
题目描述
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4
限制:
1 ≤ k ≤ 二叉搜索树元素个数
题解
二叉搜索树,中序遍历后就是递增的。
思路:
- 先中序遍历
- 找第
k个数即可。
AC 代码如下:
class Solution {
public int kthLargest(TreeNode root, int k) {
if (null == root) return -1;
List<Integer> list = new LinkedList<>();
travel(list, root);
return list.get(list.size() - k);
}
private void travel(List<Integer> list, TreeNode root) {
if (null == root) return;
travel(list, root.left);
list.add(root.val);
travel(list, root.right);
}
}
直接查找方式:
class Solution {
int res, k;
public int kthLargest(TreeNode root, int k) {
this.k = k;
dfs(root);
return res;
}
void dfs(TreeNode root) {
if(root == null) return;
dfs(root.right);
if(k == 0) return;
if(--k == 0) res = root.val;
dfs(root.left);
}
}