给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
分析:
利用bst的特性,将树转化为排序数组,再用二分查找法即可
class Solution {
public static void getArr(TreeNode node,ArrayList<Integer> arr){
if(node!=null){
getArr(node.left,arr);
arr.add(node.val);
getArr(node.right,arr);
}
}
public boolean findTarget(TreeNode root, int k) {
ArrayList<Integer> arr=new ArrayList<>();
getArr(root,arr);
int l = 0, r = arr.size() - 1;
while (l < r) {
int sum = arr.get(l) + arr.get(r);
if (sum == k)
return true;
if (sum < k)
l++;
else
r--;
}
return false;
}
}
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
分析:
利用bst树的特性,递归求解
class Solution {
public TreeNode trimBST(TreeNode root, int L, int R) {
if(root!=null){
int val=root.val;
if(val<L){
return trimBST(root.right,L,R);
}else if(val>R){
return trimBST(root.left,L,R);
}else{
root.left=trimBST(root.left,L,R);
root.right=trimBST(root.right,L,R);
}
}
return root;
}
}
分析:
双指针法,指针a1,a2
比较a1.left,a2.right
比较a2.right,a1.left
递归求解
class Solution {
public boolean check(TreeNode r1,TreeNode r2){
if(r1==null&&r2==null)return true;
if(r1==null||r2==null)return false;
return r1.val==r2.val&&check(r1.left,r2.right)&&check(r1.right,r2.left);
}
public boolean isSymmetric(TreeNode root) {
return check(root,root);
}
}
给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。在这里插入代码片
对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。
以 10^9 + 7 为模,返回这些数字之和。
分析:
利用递归双指针法,到达一个节点先判断是不是叶子节点,是则计算,不是则递归左右子树
class Solution {
static double mod=Math.pow(10,9)+7;
public int sumRootToLeaf(TreeNode root) {
if(root.left==null&&root.right==null)return root.val;
int sum=0;
sum= (int) (getNum1(root.left,root.val)%mod+getNum1(root.right,root.val)%mod);
return (int) (sum%mod);
}
public int getNum1(TreeNode node,int sum){
if(node!=null){
sum=(sum<<1)+node.val;
if(node.left==null&&node.right==null){
return sum;
}
return (getNum1(node.left,sum)+getNum1(node.right,sum));
}else return 0;
}
}
经验:左移运算符计算二进制数,避免繁琐
sum=(sum<<1)+node.val;
计算给定二叉树的所有左叶子之和。
利用flag标志当前节点是不是左节点,
双指针递归法
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if (root!=null)
return getVal(root.left,0)+getVal(root.right,1);
else return 0;
}
public int getVal(TreeNode node,int flag){
int sum=0;
if(node!=null){
if(flag==0&&node.left==null&&node.right==null){
sum+=node.val;
}
if(node.left!=null)sum+=getVal(node.left,0);
if(node.right!=null)sum+=getVal(node.right,1);
}
return sum;
}
}
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
分析:
双指针递归
可能的情况是:两棵树完全相等,左子树和其相等,右子树和其相等
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
if (t == null) return true; // t 为 null 一定都是 true
if (s == null) return false; // 这里 t 一定不为 null, 只要 s 为 null,肯定是 false
return isSubtree(s.left, t) || isSubtree(s.right, t) || isSameTree(s,t);
}
/**
* 判断两棵树是否相同
*/
public boolean isSameTree(TreeNode s, TreeNode t){
if (s == null && t == null) return true;
if (s == null || t == null) return false;
if (s.val != t.val) return false;
return isSameTree(s.left, t.left) && isSameTree(s.right, t.right);
}
}
经验:判断两棵树是否相等的函数:
public boolean isSameTree(TreeNode s, TreeNode t){
if (s == null && t == null) return true;
if (s == null || t == null) return false;
if (s.val != t.val) return false;
return isSameTree(s.left, t.left) && isSameTree(s.right, t.right);
}