Leetcode(easy Tree)
Leetcode(easy Tree)
leetcode 簡單的樹的題目,記錄一下自己的刷題過程
100. 相同的樹
給定兩個二叉樹,編寫一個函式來檢驗它們是否相同。
如果兩個樹在結構上相同,並且節點具有相同的值,則認為它們是相同的。
/** * 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 { public boolean isSameTree(TreeNode p, TreeNode q) { // myidea : 採用遞迴 比較當前傳入的節點是否相同,如果相同,就繼續遞迴遍歷其右子樹與左子樹 // 遞迴出口:如果傳入的兩個節點均不存在,則返回true,若其中一個為空,另外一個不為空,則返回false if(p == null && q == null) return true; if(p == null || q == null) return false; // 兩者皆不為空,遞迴判斷兩者的左子樹與兩者的右子樹 return (p.val == q.val) && isSameTree(p.left,q.left) && isSameTree(p.right,q.right); } }
101. 對稱二叉樹
給定一個二叉樹,檢查它是否是映象對稱的。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public boolean isSymmetric(TreeNode root) { // myidea: 也是採用遞迴,用一個額外的輔助函式,來進行判斷 return helper(root,root); } // 輔助函式,傳入的引數為根節點,然後遞迴依次判斷root1的左子樹與root2的右子樹是否相同 public boolean helper(TreeNode root1,TreeNode root2){ // 遞迴出口 // 如果傳入的兩個樹節點均不存在肯定是true if(root1 == null && root2 == null) return true; // 如果只有一個不存在,那麼肯定是錯誤的 返回false if(root1 == null || root2 == null) return false; // 判斷傳入的樹節點的值是否相同 遞迴判斷root1的左子樹與root2的右子樹,以及root1的右子樹與root2的左子樹是否相同 return (root1.val == root2.val) && helper(root1.left,root2.right) && helper(root1.right,root2.left); } }
104. 二叉樹的最大深度
給定一個二叉樹,找出其最大深度。
二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。
說明: 葉子節點是指沒有子節點的節點。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public int maxDepth(TreeNode root) { // myidea:採用遞迴 // 遞迴出口: if(root == null) return 0; // 遞迴體 return Math.max(maxDepth(root.left),maxDepth(root.right))+1; } }
107. 二叉樹的層次遍歷 II
給定一個二叉樹,返回其節點值自底向上的層次遍歷。 (即按從葉子節點所在層到根節點所在的層,逐層從左向右遍歷)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
// myidea: 層次遍歷麼,很簡單就是採用佇列的方式進行就好了,首先先計算出來整個樹的最大深度,然後記錄為flag,每次倒著更新res就可以了
List<List<Integer>> res = new ArrayList<List<Integer>>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
// 如果root為空的話
if(root == null) return res;
int flag = depth(root)-1;
for(int i = 0;i<=flag;i++) res.add(new ArrayList<Integer>());
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
for(int i = 0;i<size;i++){
TreeNode tmp = queue.poll();
res.get(flag).add(tmp.val);
if(tmp.left != null) queue.offer(tmp.left);
if(tmp.right != null) queue.offer(tmp.right);
}
flag--;
}
return res;
}
// 返回一個樹的最大深度
public int depth(TreeNode root){
if(root == null) return 0;
return Math.max(depth(root.left),depth(root.right))+1;
}
}
108. 將有序陣列轉換為二叉搜尋樹
將一個按照升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。
本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return helper(nums,0,nums.length-1);
}
public TreeNode helper(int[] nums,int left,int right){
if(left>right) return null;
int mid = (left+right)/2;
TreeNode root = new TreeNode(nums[mid]);
root.left = helper(nums,left,mid-1);
root.right = helper(nums,mid+1,right);
return root;
}
}
110. 平衡二叉樹
給定一個二叉樹,判斷它是否是高度平衡的二叉樹。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if(root==null) return true;
return Math.abs(depth(root.left)-depth(root.right))<2 && isBalanced(root.left) && isBalanced(root.right);
}
public int depth(TreeNode root){
if(root==null) return 0;
return Math.max(depth(root.left),depth(root.right)) + 1;
}
}
111. 二叉樹的最小深度
給定一個二叉樹,找出其最小深度。
最小深度是從根節點到最近葉子節點的最短路徑上的節點數量。
說明:葉子節點是指沒有子節點的節點。
112. 路徑總和
給定一個二叉樹和一個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。
說明: 葉子節點是指沒有子節點的節點。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
boolean vaild;
int pathSum;
public boolean hasPathSum(TreeNode root, int sum) {
// myidea : 採用遞迴+回溯
if(root == null) return false;
vaild = false;
pathSum = 0;
dfs(root,sum,pathSum);
return vaild;
}
public void dfs(TreeNode root,int sum,int pathSum){
// 遞迴出口
if(root !=null && sum == pathSum + root.val && root.left == null && root.right == null){
vaild = true;
return;
}
if(root == null) return;
// 遞迴
dfs(root.left,sum,pathSum+root.val);
dfs(root.right,sum,pathSum+root.val);
// 回溯
pathSum-=root.val;
return;
}
}
226. 翻轉二叉樹
翻轉一棵二叉樹。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
// myidea:遞迴
if(root == null) return root;
TreeNode left = invertTree(root.left);
TreeNode right = invertTree(root.right);
root.left = right;
root.right = left;
return root;
}
}
235. 二叉搜尋樹的最近公共祖先
給定一個二叉搜尋樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義為:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// myidea
if(root == null) return root;
if(root.val == p.val || root.val == q.val) return root;
if(p.val > root.val && q.val > root.val) return lowestCommonAncestor(root.right,p,q);
if(p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left,p,q);
return root;
}
}
257. 二叉樹的所有路徑
給定一個二叉樹,返回所有從根節點到葉子節點的路徑。
說明: 葉子節點是指沒有子節點的節點。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<String> res;
public List<String> binaryTreePaths(TreeNode root) {
// myidea:用遞迴+回溯即可
res = new LinkedList<String>();
dfs(root,"");
return res;
}
public void dfs(TreeNode node,String str){
if(node == null) return;
// 到達葉子節點
if(node.left == null && node.right == null){
str = str + node.val;
res.add(str);
return;
}
String tmp = str;
str = str + node.val + "->";
// 沒有到達葉子節點,就遍歷其兒子節點
dfs(node.left,str);
dfs(node.right,str);
// 回溯
str = tmp;
}
}
404. 左葉子之和
計算給定二叉樹的所有左葉子之和。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int res = 0;
public int sumOfLeftLeaves(TreeNode root) {
// myidea:遞迴+回溯
dfs(root,0);
return res;
}
// flag 標記位,1表示是左兒子,2表示右兒子
public void dfs(TreeNode node,int flag){
if(node == null) return;
if(node.left == null && node.right == null){
if(flag == 1) res+=node.val;
return;
}
dfs(node.left,1);
dfs(node.right,2);
}
}
501. 二叉搜尋樹中的眾數
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<Integer,Integer> map;
public int[] findMode(TreeNode root) {
// myidea:最簡單的想法就是採用層次遍歷,或者前,中,後序遍歷,用map記錄
// 但是題目中的進階不讓使用額外的空間,這時候就需要考慮二叉搜尋樹的結構性質了
// 首先先實現O(n)額外空間的實現方法
map = new HashMap<Integer,Integer>();
List<Integer> list = new ArrayList<Integer>();
preOrder(root);
int max = Integer.MIN_VALUE;
// 找到最多數字出現的次數
for(int key:map.keySet()) if(map.get(key) > max) max = map.get(key);
for(int key:map.keySet()) if(map.get(key) == max) list.add(key);
int[] res = new int[list.size()];
for(int i = 0;i<list.size();i++) res[i] = list.get(i);
return res;
}
public void preOrder(TreeNode node){
if(node == null) return;
if(!map.containsKey(node.val)) map.put(node.val,0);
map.put(node.val,map.get(node.val)+1);
preOrder(node.left);
preOrder(node.right);
}
}
530. 二叉搜尋樹的最小絕對差
給你一棵所有節點為非負值的二叉搜尋樹,請你計算樹中任意兩節點的差的絕對值的最小值。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<Integer> record = new ArrayList<Integer>();
public int getMinimumDifference(TreeNode root) {
// myidea 二叉搜尋樹的中序遍歷是一個有序陣列
inOrder(root);
int res = Integer.MAX_VALUE;
for(int i = 0;i<record.size()-1;i++) res = Math.min(res,record.get(i+1) - record.get(i));
return res;
}
public void inOrder(TreeNode root){
if(root == null) return;
inOrder(root.left);
record.add(root.val);
inOrder(root.right);
}
}
543. 二叉樹的直徑
給定一棵二叉樹,你需要計算它的直徑長度。一棵二叉樹的直徑長度是任意兩個結點路徑長度中的最大值。這條路徑可能穿過也可能不穿過根結點。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int diameterOfBinaryTree(TreeNode root) {
// myidea 不就是根的左子樹的高度與根的右子樹的高度之和麼?
// 注意題目中說了 這個路徑 可能穿過跟節點 也可能不穿過跟節點
if(root == null) return 0;
int res = Math.max((depth(root.left) + depth(root.right)),diameterOfBinaryTree(root.left));
return Math.max(res,diameterOfBinaryTree(root.right));
}
public int depth(TreeNode root){
if(root == null) return 0;
return Math.max(depth(root.left) , depth(root.right))+1;
}
}
559. N叉樹的最大深度
給定一個 N 叉樹,找到其最大深度。
最大深度是指從根節點到最遠葉子節點的最長路徑上的節點總數。
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public int maxDepth(Node root) {
// myidea 採用層次遍歷
if(root == null) return 0;
Queue<Node> queue = new LinkedList<Node>();
int depth = 0;
queue.offer(root);
while(!queue.isEmpty()){
depth++;
int size = queue.size();
for(int i = 0;i<size;i++){
Node node = queue.poll();
for(Node child:node.children) queue.offer(child);
}
}
return depth;
}
}
563. 二叉樹的坡度
給定一個二叉樹,計算 整個樹 的坡度 。
一個樹的 節點的坡度 定義即為,該節點左子樹的節點之和和右子樹節點之和的 差的絕對值 。如果沒有左子樹的話,左子樹的節點之和為 0 ;沒有右子樹的話也是一樣。空結點的坡度是 0 。
整個樹 的坡度就是其所有節點的坡度之和。
/**
* 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 {
List<Integer> list = new ArrayList<Integer>();
public int findTilt(TreeNode root) {
// myidea:藉助一個輔助list,記錄每次左右子樹的和的差值,然後利用dfs進行遍歷
if(root == null) return 0;
calSum(root);
int res = 0;
for(int num:list) res+=num;
return res;
}
// 計算整個樹的和
public int calSum(TreeNode root){
if(root == null) return 0;
int left = calSum(root.left);
int right = calSum(root.right);
list.add(Math.abs(left-right));
return left+right+root.val;
}
}
572. 另一個樹的子樹
給定兩個非空二叉樹 s 和 t,檢驗 s 中是否包含和 t 具有相同結構和節點值的子樹。s 的一個子樹包括 s 的一個節點和這個節點的所有子孫。s 也可以看做它自身的一棵子樹。
/**
* 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 {
public boolean isSubtree(TreeNode s, TreeNode t) {
if(t == null) return true;
if(s == null) return false;
return isSame(s,t) || isSubtree(s.left,t) || isSubtree(s.right,t);
}
// 判斷兩棵樹是否相同
public boolean isSame(TreeNode s,TreeNode t){
if(s == null && t == null) return true;
if(s == null || t == null) return false;
return (s.val == t.val) && isSame(s.left,t.left) && isSame(s.right,t.right);
}
}
589. N叉樹的前序遍歷
給定一個 N 叉樹,返回其節點值的前序遍歷。
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
List<Integer> res = new ArrayList<Integer>();
public List<Integer> preorder(Node root) {
//myidea : 採用深度遍歷的思想,就可以了
if(root == null) return res;
dfs(root);
return res;
}
// 深度遍歷
public void dfs(Node root){
if(root == null) return;
res.add(root.val);
for(Node child:root.children) dfs(child);
}
}
// 採用迭代法
class Solution {
public List<Integer> preorder(Node root) {
// myidea:如果使用迭代法的話,需要使用額外的資料結構,這裡使用額外的棧資料結構,
Stack<Node> stack = new Stack<>();
List<Integer> res = new LinkedList<>();
if (root == null) {
return res;
}
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
res.add(node.val);
// 將該節點所有的兒子從右到左壓入棧中
Collections.reverse(node.children);
for (Node item : node.children) {
stack.push(item);
}
}
return res;
}
}
590. N叉樹的後序遍歷
給定一個 N 叉樹,返回其節點值的後序遍歷。
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<Integer> postorder(Node root) {
Stack<Node> stack = new Stack<>();
LinkedList<Integer> res = new LinkedList<>();
if (root == null) {
return res;
}
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
res.addFirst(node.val);
for (Node item : node.children) {
if (item != null) {
stack.push(item);
}
}
}
return res;
}
}
606. 根據二叉樹建立字串
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public String tree2str(TreeNode t) {
if(t==null)
return "";
if(t.left==null && t.right==null)
return t.val+"";
if(t.right==null)
return t.val+"("+tree2str(t.left)+")";
return t.val+"("+tree2str(t.left)+")("+tree2str(t.right)+")";
}
}
617. 合併二叉樹
給定兩個二叉樹,想象當你將它們中的一個覆蓋到另一個上時,兩個二叉樹的一些節點便會重疊。
你需要將他們合併為一個新的二叉樹。合併的規則是如果兩個節點重疊,那麼將他們的值相加作為節點合併後的新值,否則不為 NULL 的節點將直接作為新二叉樹的節點。
class Solution {
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null) {
return t2;
}
if (t2 == null) {
return t1;
}
TreeNode merged = new TreeNode(t1.val + t2.val);
merged.left = mergeTrees(t1.left, t2.left);
merged.right = mergeTrees(t1.right, t2.right);
return merged;
}
}
637. 二叉樹的層平均值
給定一個非空二叉樹, 返回一個由每層節點平均值組成的陣列。
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> averages = new ArrayList<Double>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
double sum = 0;
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
sum += node.val;
TreeNode left = node.left, right = node.right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}
}
averages.add(sum / size);
}
return averages;
}
}
653. 兩數之和 IV - 輸入 BST
給定一個二叉搜尋樹和一個目標結果,如果 BST 中存在兩個元素且它們的和等於給定的目標結果,則返回 true。
public class Solution {
public boolean findTarget(TreeNode root, int k) {
List < Integer > list = new ArrayList();
inorder(root, list);
int l = 0, r = list.size() - 1;
while (l < r) {
int sum = list.get(l) + list.get(r);
if (sum == k)
return true;
if (sum < k)
l++;
else
r--;
}
return false;
}
public void inorder(TreeNode root, List < Integer > list) {
if (root == null)
return;
inorder(root.left, list);
list.add(root.val);
inorder(root.right, list);
}
}
669. 修剪二叉搜尋樹
給你二叉搜尋樹的根節點 root ,同時給定最小邊界low 和最大邊界 high。通過修剪二叉搜尋樹,使得所有節點的值在[low, high]中。修剪樹不應該改變保留在樹中的元素的相對結構(即,如果沒有被移除,原有的父代子代關係都應當保留)。 可以證明,存在唯一的答案。
所以結果應當返回修剪好的二叉搜尋樹的新的根節點。注意,根節點可能會根據給定的邊界發生改變。
class Solution {
public TreeNode trimBST(TreeNode root, int L, int R) {
if (root == null) return root;
if (root.val > R) return trimBST(root.left, L, R);
if (root.val < L) return trimBST(root.right, L, R);
root.left = trimBST(root.left, L, R);
root.right = trimBST(root.right, L, R);
return root;
}
}
671. 二叉樹中第二小的節點
給定一個非空特殊的二叉樹,每個節點都是正數,並且每個節點的子節點數量只能為 2 或 0。如果一個節點有兩個子節點的話,那麼該節點的值等於兩個子節點中較小的一個。
更正式地說,root.val = min(root.left.val, root.right.val) 總成立。
給出這樣的一個二叉樹,你需要輸出所有節點中的第二小的值。如果第二小的值不存在的話,輸出 -1 。
public int findSecondMinimumValue(TreeNode root) {
if(root == null)
return -1;
return find(root, root.val);
}
/**
* 按照題目描述
* 找到和rootValue值不相同的最小值,與rootValue不相同的最小值其實就是第二小的值。
*/
private int find(TreeNode x, int rootValue){
if(x.val != rootValue) // 如果當前結點不等於根結點至,那麼當x值為以x為根的最小的非rootValue的值
return x.val;
// 這之下都是 當前結點值為根結點值的情況
if(x.left == null) // 遞迴到葉子結點 且其值為根結點值,說明沒有找到第二小的值,返回失敗標誌-1。
return -1;
int leftMin = find(x.left, rootValue);
int rightMin = find(x.right, rootValue);
if(leftMin == -1)
return rightMin;
if(rightMin == -1)
return leftMin;
return Math.min(leftMin, rightMin);
}
700. 二叉搜尋樹中的搜尋
給定二叉搜尋樹(BST)的根節點和一個值。 你需要在BST中找到節點值等於給定值的節點。 返回以該節點為根的子樹。 如果節點不存在,則返回 NULL。
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if (root == null || val == root.val) return root;
return val < root.val ? searchBST(root.left, val) : searchBST(root.right, val);
}
}
783. 二叉搜尋樹節點最小距離
給定一個二叉搜尋樹的根節點 root,返回樹中任意兩節點的差的最小值。
class Solution {
Integer prev, ans;
public int minDiffInBST(TreeNode root) {
prev = null;
ans = Integer.MAX_VALUE;
dfs(root);
return ans;
}
public void dfs(TreeNode node) {
if (node == null) return;
dfs(node.left);
if (prev != null)
ans = Math.min(ans, node.val - prev);
prev = node.val;
dfs(node.right);
}
}
872. 葉子相似的樹
class Solution {
public boolean leafSimilar(TreeNode root1, TreeNode root2) {
List<Integer> leaves1 = new ArrayList();
List<Integer> leaves2 = new ArrayList();
dfs(root1, leaves1);
dfs(root2, leaves2);
return leaves1.equals(leaves2);
}
public void dfs(TreeNode node, List<Integer> leafValues) {
if (node != null) {
if (node.left == null && node.right == null)
leafValues.add(node.val);
dfs(node.left, leafValues);
dfs(node.right, leafValues);
}
}
}
897. 遞增順序查詢樹
給你一個樹,請你 按中序遍歷 重新排列樹,使樹中最左邊的結點現在是樹的根,並且每個結點沒有左子結點,只有一個右子結點。
class Solution {
public TreeNode increasingBST(TreeNode root) {
List<Integer> vals = new ArrayList();
inorder(root, vals);
TreeNode ans = new TreeNode(0), cur = ans;
for (int v: vals) {
cur.right = new TreeNode(v);
cur = cur.right;
}
return ans.right;
}
public void inorder(TreeNode node, List<Integer> vals) {
if (node == null) return;
inorder(node.left, vals);
vals.add(node.val);
inorder(node.right, vals);
}
}
class Solution {
TreeNode cur;
public TreeNode increasingBST(TreeNode root) {
TreeNode ans = new TreeNode(0);
cur = ans;
inorder(root);
return ans.right;
}
public void inorder(TreeNode node) {
if (node == null) return;
inorder(node.left);
node.left = null;
cur.right = node;
cur = node;
inorder(node.right);
}
}
938. 二叉搜尋樹的範圍和
給定二叉搜尋樹的根結點 root,返回 L 和 R(含)之間的所有結點的值的和。
二叉搜尋樹保證具有唯一的值。
class Solution {
int ans;
public int rangeSumBST(TreeNode root, int L, int R) {
ans = 0;
dfs(root, L, R);
return ans;
}
public void dfs(TreeNode node, int L, int R) {
if (node != null) {
if (L <= node.val && node.val <= R)
ans += node.val;
if (L < node.val)
dfs(node.left, L, R);
if (node.val < R)
dfs(node.right, L, R);
}
class Solution {
public int rangeSumBST(TreeNode root, int L, int R) {
int ans = 0;
Stack<TreeNode> stack = new Stack();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node != null) {
if (L <= node.val && node.val <= R)
ans += node.val;
if (L < node.val)
stack.push(node.left);
if (node.val < R)
stack.push(node.right);
}
}
return ans;
}
}
965. 單值二叉樹
如果二叉樹每個節點都具有相同的值,那麼該二叉樹就是單值二叉樹。
只有給定的樹是單值二叉樹時,才返回 true;否則返回 false。
class Solution {
List<Integer> vals;
public boolean isUnivalTree(TreeNode root) {
vals = new ArrayList();
dfs(root);
for (int v: vals)
if (v != vals.get(0))
return false;
return true;
}
public void dfs(TreeNode node) {
if (node != null) {
vals.add(node.val);
dfs(node.left);
dfs(node.right);
}
}
}
993. 二叉樹的堂兄弟節點
在二叉樹中,根節點位於深度 0 處,每個深度為 k 的節點的子節點位於深度 k+1 處。
如果二叉樹的兩個節點深度相同,但父節點不同,則它們是一對堂兄弟節點。
class Solution {
Map<Integer, Integer> depth;
Map<Integer, TreeNode> parent;
public boolean isCousins(TreeNode root, int x, int y) {
depth = new HashMap();
parent = new HashMap();
dfs(root, null);
return (depth.get(x) == depth.get(y) && parent.get(x) != parent.get(y));
}
public void dfs(TreeNode node, TreeNode par) {
if (node != null) {
depth.put(node.val, par != null ? 1 + depth.get(par.val) : 0);
parent.put(node.val, par);
dfs(node.left, node);
dfs(node.right, node);
}
}
}
1022. 從根到葉的二進位制數之和
給出一棵二叉樹,其上每個結點的值都是 0 或 1 。每一條從根到葉的路徑都代表一個從最高有效位開始的二進位制數。例如,如果路徑為 0 -> 1 -> 1 -> 0 -> 1,那麼它表示二進位制數 01101,也就是 13 。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int ans = 0; // 存放結果
int mod = 1000000000 + 7; // 用作取模
public int sumRootToLeaf(TreeNode root) {
helper(root, 0);
return ans % mod;
}
public void helper(TreeNode root, int sum) {
if (root != null) {
sum = sum * 2 + root.val;
if (root.left == null && root.right == null) {
ans += sum; // 到達葉子節點,得到一個和,加到結果上
} else { // 沒有到達葉子節點,繼續遞迴
helper(root.left, sum);
helper(root.right, sum);
}
}
}
}
劍指 Offer 27. 二叉樹的映象
請完成一個函式,輸入一個二叉樹,該函式輸出它的映象。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return root;
TreeNode left = mirrorTree(root.right);
TreeNode right = mirrorTree(root.left);
root.left = left;
root.right = right;
return root;
}
}
劍指 Offer 28. 對稱的二叉樹
請實現一個函式,用來判斷一棵二叉樹是不是對稱的。如果一棵二叉樹和它的映象一樣,那麼它是對稱的。
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isMirror(root,root);
}
public boolean isMirror(TreeNode root1,TreeNode root2){
if(root1 == null && root2 == null) return true;
if(root1 == null || root2 == null) return false;
return (root1.val == root2.val) && isMirror(root1.left,root2.right) && isMirror(root1.right,root2.left);
}
}
劍指 Offer 32 - II. 從上到下列印二叉樹 II
從上到下按層列印二叉樹,同一層的節點按從左到右的順序列印,每一層列印到一行。
同上
劍指 Offer 54. 二叉搜尋樹的第k大節點
給定一棵二叉搜尋樹,請找出其中第k大的節點。
class Solution {
List<Integer> list = new ArrayList<Integer>();
public int kthLargest(TreeNode root, int k) {
inOrder(root);
return list.get(list.size() - k);
}
public void inOrder(TreeNode root){
if(root == null) return;
inOrder(root.left);
list.add(root.val);
inOrder(root.right);
}
}
劍指 Offer 55 - I. 二叉樹的深度
同上
劍指 Offer 55 - II. 平衡二叉樹
同上
劍指 Offer 68 - I. 二叉搜尋樹的最近公共祖先
同上
劍指 Offer 68 - II. 二叉樹的最近公共祖先
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left == null) return right;
if(right == null) return left;
return root;
}
}
面試題 04.02. 最小高度樹
就是構造二叉搜尋樹 同上
面試題 04.04. 檢查平衡性
同上
面試題 17.12. BiNode
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode convertBiNode(TreeNode root) {
TreeNode head = new TreeNode(0);// 單鏈表的頭指標哨兵
// 開始中序遍歷
inorder(root,head);
return head.right;
}
private TreeNode inorder(TreeNode root,TreeNode prev){
if (root != null){
prev = inorder(root.left,prev);
root.left = null;
prev.right = root;
prev = root;
prev = inorder(root.right,prev);
}
return prev;
}
}