94二叉树的中序遍历
题目:给定一个二叉树的根节点 root ,返回它的中序遍历。
java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result=new ArrayList<>();
inorder(root,result);
return result;
}
public void inorder(TreeNode root,List<Integer> result){
if(root==null) return;
inorder(root.left,result);
result.add(root.val);
inorder(root.right,result);
}
}
104二叉树的最大深度
题目:给定一个二叉树 root ,返回其最大深度。二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。
java
class Solution {
public int maxDepth(TreeNode root) {
if(root==null) return 0;
int leftdepth=maxDepth(root.left);
int rightdepth=maxDepth(root.right);
return Math.max(leftdepth,rightdepth)+1;
}
}
226翻转二叉树
题目:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
java
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null) return null;
invertTree(root.left);
invertTree(root.right);
swap(root);
return root;
}
public void swap(TreeNode node){
TreeNode temp=node.left;
node.left=node.right;
node.right=temp;
}
}
101对称二叉树
题目:给你一个二叉树的根节点 root , 检查它是否轴对称。
java
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left,root.right);
}
public boolean compare(TreeNode left,TreeNode right){
if(left==null && right==null) return true;
if(left==null && right!=null) return false;
if(left!=null && right==null) return false;
if(left.val!=right.val) return false;
boolean outside = compare(left.left,right.right);
boolean inside = compare(left.right,right.left);
return outside && inside;
}
}
543二叉树的直径
题目:给你一棵二叉树的根节点,返回该树的直径 。二叉树的直径是指树中任意两个节点之间最长路径的长度 。这条路径可能经过也可能不经过根节点root 。两节点之间路径的长度由它们之间边数表示。
java
class Solution {
private int result=0;
public int diameterOfBinaryTree(TreeNode root) {
dfs(root);
return result;
}
private int dfs(TreeNode node){
if(node==null){
return -1;
}
int llen=dfs(node.left)+1;
int rlen=dfs(node.right)+1;
result=Math.max(result,llen+rlen);
return Math.max(llen,rlen);
}
}
102二叉树的层序遍历
题目:给你二叉树的根节点 root ,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。
java
class Solution {
public List<List<Integer>> result=new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
level(root);
return result;
}
public void level(TreeNode node){
Queue<TreeNode> que=new LinkedList<>();
if(node==null) return;
que.offer(node);
while(!que.isEmpty()){
List<Integer> itemList=new ArrayList<>();
int len=que.size();
while(len>0){
TreeNode temp=que.poll();
itemList.add(temp.val);
if(temp.left!=null) que.offer(temp.left);
if(temp.right!=null) que.offer(temp.right);
len--;
}
result.add(itemList);
}
}
}
108将有序数组转换为二叉搜索树
题目:给你一个整数数组 nums ,其中元素已经按升序排列,请你将其转换为一棵平衡二叉搜索树。
java
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
TreeNode root= traversal(nums,0,nums.length-1);
return root;
}
public TreeNode traversal(int[] nums,int left,int right){
if(left>right) return null;
int mid=(left+right)/2;
TreeNode root=new TreeNode(nums[mid]);
root.left=traversal(nums,left,mid-1);
root.right=traversal(nums,mid+1,right);
return root;
}
}
98 验证搜索二叉树
题目:给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效二叉搜索树定义如下:节点的左子树只包含严格小于当前节点的数。节点的右子树只包含严格大于当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。
java
class Solution {
public boolean isValidBST(TreeNode root) {
return isvalid(Long.MIN_VALUE, Long.MAX_VALUE,root);
}
boolean isvalid(long lower,long higher,TreeNode root){
if(root==null) return true;
if(root.val<=lower || root.val>= higher) return false;
return isvalid(lower,root.val,root.left) && isvalid(root.val,higher,root.right);
}
}
230 二叉搜索树第k小的元素
题目:给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(k 从 1 开始计数)。
java
class Solution {
private int k;
private int result;
public int kthSmallest(TreeNode root, int k) {
this.k=k;
dfs(root);
return result;
}
private void dfs(TreeNode root){
if(root==null || k<=0) return;
dfs(root.left);
if(--k==0){
result=root.val;
}
dfs(root.right);
}
}
199 二叉树的右视图
题目:给定一个二叉树的根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
java
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result=new ArrayList<>();
dfs(root,0,result);
return result;
}
private void dfs(TreeNode root,int depth,List<Integer> result){
if(root==null) return;
if(depth==result.size()){ // 这个深度首次遇到
result.add(root.val);
}
dfs(root.right,depth+1,result); // 先递归右子树,保证首次遇到的一定是最右边的节点
dfs(root.left,depth+1,result);
}
}
114二叉树展开为链表
题目:给你二叉树的根结点root ,请你将它展开为一个单链表:展开后的单链表应该同样使用 TreeNode ,其中right子指针指向链表中下一个结点,而左子指针始终为 null。展开后的单链表应该与二叉树先序遍历顺序相同。
java
class Solution {
private TreeNode head;
public void flatten(TreeNode root) {
if(root==null) return;
flatten(root.right);
flatten(root.left);
root.left=null;
root.right=head;
head=root;
}
}
105 从前序和中序遍历序列构造二叉树
题目:给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
java
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length==0 || inorder.length==0) return null;
return buildhelp(preorder,0,preorder.length,inorder,0,inorder.length);
}
public TreeNode buildhelp(int[] preorder,int prestart,int preend, int[] inorder, int instart, int inend){
if(prestart==preend) return null;
int rootval=preorder[prestart];
TreeNode root=new TreeNode(rootval);
if(preend-prestart==1) return root;
int midindex;
for(midindex=instart;midindex<inend;midindex++){
if(inorder[midindex]==rootval) break;
}
int leftinstart=instart;
int leftinend=midindex;
int rightinstart=midindex+1;
int rightinend=inend;
int leftprestart=prestart+1;
int leftpreend=prestart+1+(midindex-instart);
int rightprestart=prestart+1+(midindex-instart);
int rightpreend=preend;
root.left=buildhelp(preorder,leftprestart,leftpreend,inorder,leftinstart,leftinend);
root.right=buildhelp(preorder,rightprestart,rightpreend,inorder,rightinstart,rightinend);
return root;
}
}
437路径总和III
题目:给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的路径的数目。路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
java
class Solution {
private int ans;
public int pathSum(TreeNode root, int targetSum) {
Map<Long,Integer> cnt=new HashMap<>(); // key从根到 node 的节点值之和, value节点值之和的出现次数
cnt.put(0L,1);
dfs(root,0,targetSum,cnt);
return ans;
}
private void dfs(TreeNode node,long s,int targetSum,Map<Long,Integer> cnt){
if(node==null){
return;
}
s=s+node.val; // s 表示从根到 node 的父节点的节点值之和(node 的节点值尚未计入)
ans=ans+cnt.getOrDefault(s-targetSum,0);
cnt.merge(s,1,Integer::sum); // cnt[s]++
dfs(node.left,s,targetSum,cnt);
dfs(node.right,s,targetSum,cnt);
cnt.merge(s,-1,Integer::sum); // cnt[s]-- 恢复现场(撤销 cnt[s]++)
}
}
236 二叉树的最近公共祖先
题目:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:"对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。"
java
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 && right==null){
return null;
}else if(left!=null && right==null){
return left;
}else if(left==null && right!=null){
return right;
}else{
return root;
}
}
}
124 二叉树中的最大路径和
题目:二叉树中的路径被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中至多出现一次。该路径至少包含一个节点,且不一定经过根节点。路径和是路径中各节点值的总和。给你一个二叉树的根节点 root ,返回其最大路径和。
java
class Solution {
private int result=Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
dfs(root);
return result;
}
private int dfs(TreeNode node){
if(node==null){
return 0;
}
int lval=dfs(node.left);
int rval=dfs(node.right);
result=Math.max(result,lval+node.val+rval);
return Math.max(Math.max(lval,rval)+node.val,0);
}
}