🍓二叉树篇
🍊题一:144. 二叉树的前序遍历
⭐️思路:
⭐️代码:
/**
* 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 List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
if(root==null) return res;
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node=stack.pop();
res.add(node.val);
if(node.right!=null){
stack.push(node.right);
}
if(node.left!=null){
stack.push(node.left);
}
}
return res;
}
}
🍊题二:145. 二叉树的后序遍历
⭐️思路:
⭐️代码:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
if(root==null) return res; //注意是返回res 而不是null
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node=stack.pop();
res.add(node.val);
if(node.left!=null){
stack.push(node.left);
}
if(node.right!=null){
stack.push(node.right);
}
}
Collections.reverse(res);
return res;
}
}
🍊题三: 94. 二叉树的中序遍历
⭐️思路:
⭐️代码:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
if(root==null) return res;
Stack<TreeNode> stack=new Stack<>();
while(root!=null||!stack.isEmpty()){
while(root!=null){
stack.push(root);
root=root.left;
}
root=stack.pop();
res.add(root.val);
root=root.right;
}
return res;
}
}
🍊题四:114. 二叉树展开为链表
⭐️思路:
⭐️代码:
/**
* 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 void flatten(TreeNode root) {
if(root==null){
return;
}
flatten(root.left);//递归拉平左右子树
flatten(root.right);
TreeNode left=root.left; //将左子树变成链表
TreeNode right=root.right;
TreeNode t=right;
root.left=null;
root.right=left; //将左子树作为右子树
while(root.right!=null)root=root.right;//将原先的右子树接到当前右子树的末端
root.right=right; //遍历完右节点后,将原先右子树接到如今的右节点上
}
}
🍊题五:101. 对称二叉树
⭐️思路:
⭐️代码:
/**
* 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 isSymmetric(TreeNode root) {
if(root==null)return true;
return check(root.left,root.right);
}
boolean check(TreeNode left,TreeNode right){
if(left==null&&right==null)return true;
if(left==null||right==null)return false;
if(left.val!=right.val)return false;
return check(left.left,right.right)&&check(left.right,right.left);
}
}
🍎100. 相同的树
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null) return true;
if(p==null||q==null) return false;
if(p.val!=q.val) return false;
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
}
🍊题六:104. 二叉树的最大深度
⭐️思路:
⭐️代码:
/**
* 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 int maxDepth(TreeNode root) {
if(root==null) return 0;
int leftMax=maxDepth(root.left);
int rightMax=maxDepth(root.right);
return 1+Math.max(leftMax,rightMax);
}
}
🍊题六:226. 翻转二叉树
⭐️思路:
⭐️代码:
/**
* 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 TreeNode invertTree(TreeNode root) {
if(root==null)return null;
invertTree(root.left);
invertTree(root.right);
TreeNode t=root.left;
root.left=root.right;
root.right=t;
return root;
}
}
🍊题七:538. 把二叉搜索树转换为累加树
⭐️思路:
⭐️代码:
/**
* 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 {
int sum=0;
public TreeNode convertBST(TreeNode root) {
if(root!=null){
convertBST(root.right);
sum += root.val;
root.val=sum;
convertBST(root.left);
}
return root;
}
}
🍊题八:235. 二叉搜索树的最近公共祖先
⭐️思路:
⭐️代码:
/**
* 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) {
if(root.val>p.val&&root.val>q.val){
return lowestCommonAncestor(root.left,p,q);
}
if(root.val<p.val&&root.val<q.val){
return lowestCommonAncestor(root.right,p,q);
}
return root;
}
}
🍎236. 二叉树的最近公共祖先
⭐️思路:
⭐️代码:
/**
* 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) {
if(root==null)return null;
if(root.val==p.val||root.val==q.val) //若root遇到目标值,就返回目标值
return root;
TreeNode left=lowestCommonAncestor(root.left,p,q);
TreeNode right=lowestCommonAncestor(root.right,p,q);
if(left==null) return right;//左子树没有p,q.返回该右节点找
if(right==null)return left;
return root;//该节点的左右子树都不会空,返回这个节点
}
}
🍊题九:617. 合并二叉树
⭐️思路:
⭐️代码:
/**
* 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 TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1==null) return root2;
if(root2==null) return root1;
root1.val+=root2.val;
root1.left=mergeTrees(root1.left,root2.left);
root1.right=mergeTrees(root1.right,root2.right);
return root1;
}
}
🍊题九:
⭐️思路:
⭐️代码:
🍊题九:
⭐️思路:
⭐️代码:
🍇关于构造树的题目
🍇题九:654. 最大二叉树
⭐️思路:
设置递归函数 TreeNode build(int[] nums, int l, int r) 含义为从 nums 中的 [l, r][l,r] 下标范围进行构建,返回构建后的头结点。
当 l > rl>r 时,返回空节点,否则在 [l, r][l,r] 中进行扫描,找到最大值对应的下标 idx 并创建对应的头结点,递归构建 [l, idx - 1][l,idx−1] 和 [idx + 1, r][idx+1,r] 作为头节点的左右子树。
⭐️代码:
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return build(nums,0,nums.length-1);
}
public TreeNode build(int[] nums,int lo,int hi){
if(lo>hi)return null;
int index=lo;
int max=-1;
for(int i=lo;i<=hi;i++){
if(max<nums[i]){
max=nums[i];
index=i;
}
}
TreeNode root=new TreeNode(max);
root.left=build(nums,lo,index-1);
root.right=build(nums,index+1,hi);
return root;
}
}
🍇题十:105. 从前序与中序遍历序列构造二叉树
⭐️思路:
⭐️代码:
/**
* 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 {
HashMap<Integer,Integer> valToIndex=new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
for(int i=0;i<inorder.length;i++){
valToIndex.put(inorder[i],i);
}
return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
TreeNode build(int[] preorder,int preStar,int preEnd,
int[] inorder,int inStar,int indEnd){
if(preStar>preEnd)return null;
int rootVal=preorder[preStar];
int index=valToIndex.get(rootVal);
int leftsize=index-inStar;
//先构造当前节点
TreeNode root=new TreeNode(rootVal);
//递归构造左右子树
root.left=build(preorder,preStar+1,leftsize+preStar,
inorder,inStar,index-1);
root.right=build(preorder,leftsize+preStar+1,preEnd,
inorder,index+1,indEnd);
return root;
}
}
🍇题十一:889. 根据前序和后序遍历构造二叉树
⭐️思路:
⭐️代码:
class Solution {
// 存储 postorder 中值到索引的映射
HashMap<Integer, Integer> valToIndex = new HashMap<>();
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
for (int i = 0; i < postorder.length; i++) {
valToIndex.put(postorder[i], i);
}
return build(preorder, 0, preorder.length - 1,
postorder, 0, postorder.length - 1);
}
// 定义:根据 preorder[preStart..preEnd] 和 postorder[postStart..postEnd]
// 构建二叉树,并返回根节点。
TreeNode build(int[] preorder, int preStart, int preEnd,
int[] postorder, int postStart, int postEnd) {
if (preStart > preEnd) {
return null;
}
if (preStart == preEnd) {
return new TreeNode(preorder[preStart]);
}
// root 节点对应的值就是前序遍历数组的第一个元素
int rootVal = preorder[preStart];
// root.left 的值是前序遍历第二个元素
// 通过前序和后序遍历构造二叉树的关键在于通过左子树的根节点
// 确定 preorder 和 postorder 中左右子树的元素区间
int leftRootVal = preorder[preStart + 1];
// leftRootVal 在后序遍历数组中的索引
int index = valToIndex.get(leftRootVal);
// 左子树的元素个数
int leftSize = index - postStart + 1;
// 先构造出当前根节点
TreeNode root = new TreeNode(rootVal);
// 递归构造左右子树
// 根据左子树的根节点索引和元素个数推导左右子树的索引边界
root.left = build(preorder, preStart + 1, preStart + leftSize,
postorder, postStart, index);
root.right = build(preorder, preStart + leftSize + 1, preEnd,
postorder, index + 1, postEnd - 1);
return root;
}
}
🍊题十二:
⭐️思路:
⭐️代码:
🍊题十三:
⭐️思路:
⭐️代码:
🍊题九:
⭐️思路:
⭐️代码:
🍊题九:
⭐️思路:
⭐️代码: