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;
}
}