第十五天 搜索与回溯算法 (中等)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof
题目
给你二叉树的根节点 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]]
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3:
输入:root = [1,2], targetSum = 0
输出:[]
提示:
树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
解题思路:
路径是要从根节点到叶子节点的,不用剪枝。
代码
/**
import java.util.ArrayList;
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
LinkedList<List<Integer>> result = new LinkedList<>();
LinkedList<Integer> temp = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int target) {
dfs(root, target);
return result;
}
private void dfs(TreeNode root, int target){
if(root == null) return;
temp.add(root.val);
target -= root.val;
if(target == 0 && root.left == null && root.right == null) result.add(new LinkedList(temp));
dfs(root.left, target);
dfs(root.right, target);
temp.removeLast();
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof
题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
解题思路:
中序遍历的同时,构建双链表。
有思路,链表实现还是差点。10分钟做不出来,看了题解。。希望再刷能做出来
代码
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
Node head, pre; // head 头节点, pre 当前结点
public Node treeToDoublyList(Node root) {
if(root == null) return null;
dfs(root);
// 头尾相连
head.left = pre;
pre.right = head;
return head;
}
private void dfs(Node cur) {
if(cur == null) return;
// 递归 “左-中-右” 二叉搜索树的中序遍历结果即为递增序列
dfs(cur.left);
if(pre != null) {
pre.right = cur;
}else {
head = cur;
}
cur.left = pre;
pre = cur;
dfs(cur.right);
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof
题目
给定一棵二叉搜索树,请找出其中第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 个即为题目所求。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
static int message;
int count = 0;
public int kthLargest(TreeNode root, int k) {
dfs(root, k);
return message;
}
private void dfs(TreeNode root, int k) {
if(root == null) return;
dfs(root.right, k);
if(k == ++count) {
message = root.val;
return;
}
dfs(root.left, k);
}
}