兩數之和 IV - 輸入 BST
給定一個二叉搜索樹和一個目標結果,如果 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);
}