对称二叉树
/**
* 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 dfs(root.left,root.right);
}
public boolean dfs(TreeNode right , TreeNode left){
if(right==null && left!=null) return false;
else if(right!=null && left==null) return false;
else if(right.val!=left.val) return false;
else if(right!=null && left!=null) return true;
// 左节点的左孩子 和右节点的右孩子 是否相等
boolean outside =dfs(left.left,right.right);
// 左节点的右孩子 和右节点的左孩子 是否相等
boolean inside = dfs(left.right,right.left);
boolean is = outside&&inside;
return is;
}
}
二叉树的最大深度
递归
/**
* 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) {
return dfs(root);
}
public int dfs(TreeNode root){
if(root==null) return 0;
Deque<TreeNode> stack = new LinkedList<>();
int ld= dfs(root.right);
int rd= dfs(root.left);
int d = 1 +Math.max(ld,rd);
return d;
}
}
迭代
/**
* 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) {
Deque<TreeNode> stack = new LinkedList<>();
if(root==null) return 0;
stack.add(root);
int d = 0;
while(!stack.isEmpty()){
int cur = stack.size();
for(int i =0;i<cur;i++){
TreeNode node = stack.pop();
if(node.left!=null) stack.add(node.left);
if(node.right!=null)stack.add(node.right);
}
d++;
}
return d;
}
}
/**
* 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 minDepth(TreeNode root) {
if(root==null) return 0;
return mind(root);
}
public int mind(TreeNode node){
if(node==null) return 0;
int ld = mind(node.left);
int rd = mind(node.right);
if(node.left == null && node.right!=null){
return rd+1;
}
if(node.left != null && node.right==null){
return ld+1;
}
int s = 1+Math.min(ld,rd);
return 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 List<String> binaryTreePaths(TreeNode root) {
List<String> paths = new ArrayList<>();
constructPatchs(root,"",paths);
return paths;
}
public void constructPatchs(TreeNode root,String path,List<String> paths){
if(root!=null){
StringBuffer pathSB = new StringBuffer(path);
pathSB.append(Integer.toString(root.val));
if(root.left==null && root.right==null){ // 左右孩子都为空 说明当前结点已经是叶子结点了
paths.add(pathSB.toString()); // 将当前路径放到答案里
}else{
pathSB.append("->");// 当前不是叶子结点
constructPatchs(root.left,pathSB.toString(),paths);
constructPatchs(root.right,pathSB.toString(),paths);
}
}
}
}
//放心大胆的递归吧
广度优先搜索
/**
* 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<String> binaryTreePaths(TreeNode root) {
List<String> res = new LinkedList<>();
if(root==null) return res;
Queue<TreeNode> stack = new LinkedList<>();
Queue<String> paths = new LinkedList<>();
stack.offer(root);
paths.offer(Integer.toString(root.val));
while(!stack.isEmpty()){
TreeNode node = stack.poll();
String path = paths.poll();
if(node.left==null&&node.right==null){
res.add(path);
}else{
if(node.left!=null){
stack.offer(node.left);
paths.offer(new StringBuffer(path).append("->").append(node.left.val).toString());
}
if(node.right!=null){
stack.offer(node.right);
paths.offer(new StringBuffer(path).append("->").append(node.right.val).toString());
}
}
}
return res;
}
}
找树的左下角的值
/**
* 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 findBottomLeftValue(TreeNode root) {
dfs(root,0);
return leftValue;// 首先 了解到我们要返回的是一个整形的 左下角的点的值。
}
int maxLength = -1;
int leftValue;
// 了解到 我们需要找到最后一层 然后找最后一层的最左边的结点
public void dfs(TreeNode node , int curLength){
if(node.left==null && node.right==null){//终止条件就是 左孩子 右孩子都为空 说明该结点是叶子结点。
if(curLength>maxLength){ // 寻找到最大深度 最大深度就需要 中 左右 的遍历顺序 即 前序遍历
maxLength = curLength; // 如果当前深度比上一个深度深 可以赋值
leftValue = node.val;
}
return ;
}
if(node.left!=null){ // 左节点不为空向左递归 要先左 后右 这样可以优先赋值左节点 深度更新 右节点就跳过了
curLength++;
dfs(node.left,curLength);
curLength--; // 要回朔
}
if(node.right!=null){
curLength++;
dfs(node.right,curLength);
curLength--;
}
}
}
迭代
/**
* 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 findBottomLeftValue(TreeNode root) {
// 层序遍历大法 干干干
if(root==null) return 0;
Queue<TreeNode> stack = new LinkedList<>();
stack.offer(root);
int res=0;
while(!stack.isEmpty()){
int size = stack.size();
for(int i = 0;i<size;i++){
TreeNode node = stack.poll();
if(i==0) res=node.val;
if(node.left!=null) stack.offer(node.left);
if(node.right!=null) stack.offer(node.right);
}
}
return res;
}
}
路径总和
唉 也放心了 也大胆了 就是缝缝补补 修改了半天
可怜啊~~~~~~~~~~~~~~~
/**
* 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 hasPathSum(TreeNode root, int targetSum) {
if(root==null) return false;
return helper(root,targetSum-root.val);
}
// 放心大胆的递归
public boolean helper(TreeNode node , int targetSum){
if(node.left == null && node.right==null && targetSum==0) return true;
if(node.left==null && node.right==null) return false;
if(node.left!=null){
targetSum = targetSum - node.left.val;
if(helper(node.left,targetSum)) return true;
targetSum+=node.left.val;
}
if(node.right!=null){
targetSum = targetSum - node.right.val;
if(helper(node.right,targetSum)) return true;
targetSum+=node.right.val;
}
return false;
}
}
构造二叉树
/**
* 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 buildTree(int[] inorder, int[] postorder) {
return helper(inorder,postorder);
}
public TreeNode helper(int[] inorder,int[] postorder){
if(postorder.length==0) return null; // 如果后序数组大小为0 说明没有结点了
int rootValue = postorder[postorder.length-1]; // 后序数组的最后一个数为当前树的根结点
TreeNode root = new TreeNode(rootValue); //
if(postorder.length==1) return root;
int segementpoint; // 中序数组的分割点
for(segementpoint = 0;segementpoint<inorder.length;segementpoint++){
if(inorder[segementpoint]==rootValue) break;
}
//切割中序数组,得到中序左数组和中序右数组
int[] leftInorder = Arrays.copyOfRange(inorder, 0,segementpoint);
int[] rightInorder = Arrays.copyOfRange(inorder, segementpoint+1,inorder.length);
//切割后序数组,得到后序左数组和后序右数组
postorder=Arrays.copyOfRange(postorder,0,postorder.length-1); // 因为最后一个数字 作为分割结点所以 删除最后一个结点
int[] leftPostorder=Arrays.copyOfRange(postorder, 0,leftInorder.length);
int[] rightPostorder=Arrays.copyOfRange(postorder, leftInorder.length,postorder.length);
root.left=helper(leftInorder,leftPostorder);
root.right=helper(rightInorder,rightPostorder);
return root;
}
}
同样的原理,本方法不需要重复赋值数组,同时通过 map对根结点进行查找、节省了空间复杂度和时间复杂度
/**
* 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 post_idx;
int[] postorder;
int[] inorder;
Map<Integer, Integer> idx_map = new HashMap<Integer, Integer>();
public TreeNode helper(int in_left, int in_right) {
// 如果这里没有节点构造二叉树了,就结束
if (in_left > in_right) {
return null;
}
// 选择 post_idx 位置的元素作为当前子树根节点
int root_val = postorder[post_idx];
TreeNode root = new TreeNode(root_val);
// 根据 root 所在位置分成左右两棵子树
int index = idx_map.get(root_val);
// 下标减一
post_idx--;
// 构造右子树
root.right = helper(index + 1, in_right);
// 构造左子树
root.left = helper(in_left, index - 1);
return root;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.postorder = postorder;
this.inorder = inorder;
// 从后序遍历的最后一个元素开始
post_idx = postorder.length - 1;
// 建立(元素,下标)键值对的哈希表
int idx = 0;
for (Integer val : inorder) {
idx_map.put(val, idx++);
}
return helper(0, inorder.length - 1);
}
}
前序中序构造二叉树
/**
* 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 root_index ;
int[] preorder;
int[] inorder;
Map<Integer,Integer> map = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder=preorder;
this.inorder=inorder;
root_index = 0;
int index = 0;
for(int i:inorder){
map.put(i,index++);
}
return helper(0,inorder.length-1);
}
// 左边界 与 右边界指的是 前序遍历中的! 前序遍历中的! 前序遍历中的! 对左右边界进行更新
public TreeNode helper(int left_bord , int right_bord){
if(left_bord>right_bord) return null;
// 获得根结点
int root_val=preorder[root_index];
//在中序遍历中定位根结点
int inorder_root = map.get(root_val);
// 创建子树
TreeNode root = new TreeNode(root_val);
//根结点进行加一 可以获得左子树的根结点
root_index++;
//分割中序遍历
int bord = map.get(root_val);
// 在这里就是对左右边界进行了更新
root.left=helper(left_bord,bord-1); // 左子树
root.right=helper(bord+1,right_bord); // 右子树
return root;
}
}
最大二叉树
/**
* 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 constructMaximumBinaryTree(int[] nums) {
return helper(nums,0,nums.length);
}
//第一步找到数组中的最大值为根节点
//第二步根结点左侧的最大值为左子树根结点
//第三步根结点右侧的最大值为右子树的根结点
//递归
// 实际就是 确定最大值位置 然后左子树为左数组的最大值 右子树为右数组的最大值
// 确定 输入的参数 以及 返回值类型
// 确定递归终止条件
// 确定逻辑语句
public TreeNode helper(int[] nums,int l,int r){
if(l==r) return null;
int max_i = max(nums,l,r);
TreeNode root = new TreeNode(nums[max_i]);
root.left=helper(nums,l,max_i);
root.right=helper(nums,max_i+1,r);
return root;
}
public int max(int[]nums,int l ,int r){
int max_i = l;
for(int i = l;i<r;i++){
if(nums[max_i]<nums[i]){
max_i=i;
}
}
return max_i;
}
}
合并二叉树
/**
* 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) {
return helper(root1,root2);
}
//递归
// 前序遍历
//返回一个树 输入参数为两个树
public TreeNode helper(TreeNode root1 , TreeNode root2){
//递归终止条件
if(root1==null&&root2==null) return null;
if(root1==null) return root2;//如果root1为空 则返回root2
if(root2==null) return root1;
// 逻辑语句
root1.val+=root2.val;
root1.left=helper(root1.left,root2.left);
root1.right=helper(root1.right,root2.right);
return root1;
}
}
二叉搜索树中的搜素
递归
/**
* 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 searchBST(TreeNode root, int val) {
return helper(root,val);
}
public TreeNode helper(TreeNode root,int val){
if(root==null||root.val==val) return root;
if(root.val>val) return helper(root.left,val);
if(root.val<val) return helper(root.right,val);
return null;
}
}
迭代
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
while(root!=null){
if(val>root.val){
root=root.right;
}else if(val<root.val){
root=root.left;
}else{
return root;
}
}
return null;
// 如果val 大于当前值 则向右寻找 加入他的右孩子
}
}
验证二叉搜索树
递归
/**
* 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 isValidBST(TreeNode root) {
return helper(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
public boolean helper(TreeNode node ,long lower,long upper){
if(node == null){
return true;
}
if(node.val<=lower || node.val>=upper){
return false;
} // 大于最小值 小于根结点 小于最大值 大于根结点
return helper(node.left,lower,node.val) && helper(node.right,node.val,upper);
}
}
迭代
/**
* 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 isValidBST(TreeNode root) {
Deque<TreeNode> stack = new LinkedList<>();
double inorder = -Double.MAX_VALUE;
while(!stack.isEmpty() || root!=null){
while(root!=null){
stack.push(root);
root=root.left;
}
root =stack.pop();
if(root.val<=inorder){
return false;
}
inorder = root.val;
root=root.right;
}
return true;
}
}