java数据结构之二叉树(2)

对称二叉树

在这里插入图片描述

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

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值