【Leecode笔记】第二十四周(3.22-3.28) 树专题+回溯算法

本文主要介绍了LeetCode中的树专题和回溯算法相关题目,包括前序遍历构造二叉搜索树、二叉搜索树的插入操作、层序遍历等,并探讨了回溯算法在解决组合、电话号码字母组合等问题中的应用。同时,对动态规划和二分查找等方法进行了分析。
摘要由CSDN通过智能技术生成

这周的回溯完成的不好,两天没写都忘完了…挖个坑

【第一题】前序遍历构造二叉搜索树

在这里插入图片描述

分析:首先思路是这样的,每从数组中取出一个数,就从根节点开始比较,假如比根节点小,那么就从根节点的左子树找位置,否则在右子树找位置,直到找到一个空位子插入。

现在问题在于,没有递归向下找节点,而是一味代替根节点的左右子树!

class Solution {
   
    TreeNode pre;
    public TreeNode bstFromPreorder(int[] preorder) {
   
        if(preorder.length == 0){
   return null;}
        TreeNode root = new TreeNode(preorder[0]);
        pre = root;
        //数组中的每个元素都是从根节点开始比较的
        for(int i = 1;i < preorder.length;i++){
   
            TreeNode node = new TreeNode(preorder[i]);
            TreeNode r = dfs(root,preorder[i]);
            if(r.val < preorder[i]){
   
                r.right = node;
            }else{
   
                r.left = node;
            }
        }
        return pre;
    }
    private TreeNode dfs(TreeNode root,int k){
   
        if(root == null){
   return null;}
        if(root.val < k){
   
            dfs(root.right,k);
        }
        if(root.val >= k){
   
            dfs(root.left,k);
        }
        return root;
    }
}
class Solution {
   
    public TreeNode bstFromPreorder(int[] preorder) {
   
		TreeNode root = new TreeNode(preorder[0]);
		for(int i = 1;i < preorder.length;i++){
   
			dfs(root,preorder[i]);
		}
		return root;
	}
	public void dfs(TreeNode root,int num){
   
		TreeNode node = new TreeNode(num);
		TreeNode p = root;
		while(true){
   
			if(p.val > num){
   
				if(p.left != null){
   
					p= p.left;
				}else{
   
					p.left = node;
					break;
				}
			}else{
   
				if(p.right != null){
   
					p= p.right;
				}else{
   
					p.right = node;
					break;
				}
			}
		}
	}
}

【第二题】二叉搜索树中的插入操作

在这里插入图片描述

分析:和第一题有点像。

//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:39 MB, 在所有 Java 提交中击败了78.13% 的用户
class Solution {
   
    public TreeNode insertIntoBST(TreeNode root, int val) {
   
        if(root == null){
   
            return new TreeNode(val);
        }
        dfs(root,val);
        return root;
    }
    public void dfs(TreeNode root,int val){
   
        TreeNode node = new TreeNode(val);
        TreeNode p = root;
        while(true){
   
            if(p.val > val){
   
                if(p.left !=null){
   
                    p = p.left;
                }else{
   
                    p.left = node;
                    break;
                }
            }else{
   
                if(p.right !=null){
   
                    p = p.right;
                }else{
   
                    p.right = node;
                    break;
                }
            }
        }
    }
}

【第三题】二叉树的层序遍历II

在这里插入图片描述

分析:可以这样,将每次queue.size()都存入栈,然后将所有节点都入队之后,根据栈中的值,弹出相应数量的节点(注意这里,加入列表时需要完成一次逆序)

需要用到的数据结构:一个队列(进行程序遍历)、一个存放所有节点的栈,一个存放每层节点数目的栈,一个记录每层节点的list。
虽然说思路清晰,但是挺慢的…

class Solution {
   
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
   
        List<List<Integer>> l = new ArrayList<>();
        if(root == null){
   return l;}
        //进行层序遍历的栈
        Queue<TreeNode> q = new LinkedList<>();
        //存放所有节点的s1
        Stack<TreeNode> s1 = new Stack<>();
        //存放每层节点数目的s2
        Stack<Integer> s2 = new Stack<>();

        q.add(root);
        //遍历一遍统计信息
        while(!q.isEmpty()){
   
            int count = q.size();
            s2.push(count);
            for(int i = 0;i < count;i++){
   
                TreeNode node = q.poll();
                s1.push(node);
                if(node.left!=null){
   
                    q.add(node.left);
                }
                if(node.right!=null){
   
                    q.add(node.right);
                }
            }
        }
        //倒出节点,加入列表
        while(!s1.isEmpty()){
   
            int tmp = s2.pop();
            List<Integer> list = new ArrayList<>();
            for(int i = 0;i < tmp;i++){
   
                TreeNode node =<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值