每日三题-二叉树的层序遍历、二叉树的中序遍历、最小覆盖子串

简介: 每日三题二叉树的层序遍历二叉树的中序遍历最小覆盖子串

二叉树的层序遍历


6f7aeb2eb4364e4ebd6ede5b75d341e6.png

解法一

BFS

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if(root == null) return res;
        LinkedList<TreeNode> list = new LinkedList<>();
        list.add(root);
        while(!list.isEmpty()){
            int size = list.size();
            List<Integer> l = new ArrayList<>();
            for(int i = 0;i < size;i++){
                TreeNode t = list.pop();
                l.add(t.val);
                if(t.left != null)list.add(t.left);
                if(t.right != null)list.add(t.right);
            }
            res.add(l);
        }
        return res;
    }
}


二叉树的中序遍历


7dbfbf4ec08e4831a6c1504cf509b3fb.png


解法一

递归

最简单

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        fun(root,list);
        return list;
    }
    public void fun(TreeNode root,List<Integer> list){
        if(root == null)return;
        fun(root.left,list);
        list.add(root.val);
        fun(root.right,list);
    }
}

解法二

自己维护栈

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null) return list;
        Stack<TreeNode> stack = new Stack<>();
        while(root != null || !stack.isEmpty()){
            while(root != null){
                stack.add(root);
                root = root.left;
            }
            TreeNode node = stack.pop();
            list.add(node.val);
            root = node.right;
        }
        return list;
    }
}


最小覆盖子串


02f2842ab97748ab901dfb2d237eb82f.png

解法一

暴力枚举

外层循环枚举起始值

内层循环枚举结束值

然后比较数组

class Solution {
    public String minWindow(String s, String t) {
        int slen = s.length();
        int tlen = t.length();
        if(slen < tlen) return "";
        int res = slen + 1;
        int left = 0;
        char [] arrs = s.toCharArray();
        char [] arrt = t.toCharArray();
        int [] s1 = new int[128];
        int [] t1 = new int[128];
        for(int i = 0;i < tlen;i++){
            t1[arrt[i]]++;
        }
        for(int i = 0;i < slen;i++){ // 枚举起始位置
            Arrays.fill(s1,0);
            for(int j = i;j < slen;j++){ // 枚举结束位置
                s1[arrs[j]]++;
                if(j-i+1 < tlen) continue;
                if(check(s1,t1)){
                    System.out.println(i+" "+j);
                    if(res > j-i+1){
                        res = j-i+1;
                        left = i;
                    }
                    break;
                }
            }
        }
        if(res == slen+1) return "";
        StringBuilder sb = new StringBuilder();
        for(int i = left;i < left+res;i++){
            sb.append(arrs[i]);
        }
        return sb.toString();
    }
    public boolean check(int[] arrs,int[] arrt){
        for(int i = 0;i < arrs.length;i++){
            if(arrs[i] < arrt[i]){
                return false;
            }
        }
        return true;
    }
}

解法二

滑动窗口

class Solution {
    public String minWindow(String s, String t) {
        int slen = s.length();
        int tlen = t.length();
        if(slen < tlen) return "";
        int minLen = slen + 1;
        int begin = 0;
        int left = 0;
        int right = 0;
        int distance = 0;
        char [] arrs = s.toCharArray();
        char [] arrt = t.toCharArray();
        int [] s1 = new int[128];
        int [] t1 = new int[128];
        for(int i = 0;i < tlen;i++){
            t1[arrt[i]]++;
        }
        while(right < slen){   
            //1. 如果当前字符没有在t中
            if(t1[arrs[right]] == 0){
                s1[arrs[right]]++;
                right++;
                continue;
            }
            //2. 到这里说明当前字符在t中存在
            //2.1 当left - right中这个字符的个数少于t1中这个字符个数时候才加一
            // 因为当等于或者大于的时候,说明s1中这个的字符与t1中相等或者大于,但是他实际包含的t1的长度是t1中字符的长度 
            if(s1[arrs[right]] < t1[arrs[right]]){
                distance++;
            }
            s1[arrs[right]]++;
            right++;
            //3.说明找到一个字符串满足条件了,就开始收缩左边界
            while(distance == tlen){
                if(right - left < minLen){
                    minLen = right-left;
                    begin = left;
                }
                if(s1[arrs[left]] == t1[arrs[left]]){
                    distance--;
                }
                s1[arrs[left]]--;
                left++;
            }            
        }
        if(minLen == slen + 1) return "";
        return s.substring(begin,begin+minLen);
    }
}
相关文章
【LeetCode】105. 从前序与中序遍历序列构造二叉树
题目描述: 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示例:
66 0
|
2月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
34 0
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
62 0
|
7月前
|
机器学习/深度学习 C++
初阶数据结构之---二叉树链式结构(二叉树的构建,二叉树的前序,中序,后序和层序遍历,计算二叉树结点个数,第k层结点个数,叶子结点个数,判断是否为完全二叉树)
初阶数据结构之---二叉树链式结构(二叉树的构建,二叉树的前序,中序,后序和层序遍历,计算二叉树结点个数,第k层结点个数,叶子结点个数,判断是否为完全二叉树)
|
7月前
|
C++ 索引 Python
leetcode-105:从前序与中序遍历序列构造二叉树
leetcode-105:从前序与中序遍历序列构造二叉树
50 0
|
7月前
|
算法
二叉树的结点个数、叶子结点个数的代码实现<分治算法>
二叉树的结点个数、叶子结点个数的代码实现<分治算法>
每日一题:LeetCode-589.N叉树的前序遍历序列构造二叉树
每日一题:LeetCode-589.N叉树的前序遍历序列构造二叉树
|
机器学习/深度学习 算法 Java
代码随想录训练营day16|104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数...
代码随想录训练营day16|104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数...
|
C++
力扣 - 106、从中序与后序遍历序列构造二叉树
力扣 - 106、从中序与后序遍历序列构造二叉树
105 0