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

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

二叉树的层序遍历


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);
    }
}
相关文章
|
3天前
二叉树基础oj练习(对称二叉树、翻转二叉树、另一棵树的子树二叉树的构建及遍历)
二叉树基础oj练习(对称二叉树、翻转二叉树、另一棵树的子树二叉树的构建及遍历)
26 0
|
7月前
【LeetCode】105. 从前序与中序遍历序列构造二叉树
题目描述: 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示例:
33 0
|
7月前
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
35 0
|
3天前
【力扣】104. 二叉树的最大深度、111. 二叉树的最小深度
【力扣】104. 二叉树的最大深度、111. 二叉树的最小深度
|
3天前
|
C++ 索引 Python
leetcode-105:从前序与中序遍历序列构造二叉树
leetcode-105:从前序与中序遍历序列构造二叉树
33 0
|
5月前
|
算法
每日一题:LeetCode-589.N叉树的前序遍历序列构造二叉树
每日一题:LeetCode-589.N叉树的前序遍历序列构造二叉树
|
11月前
|
机器学习/深度学习 算法 Java
代码随想录训练营day16|104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数...
代码随想录训练营day16|104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数...
|
11月前
剑指offer_二叉树---二叉树中和为某一值的路径
剑指offer_二叉树---二叉树中和为某一值的路径
58 0
LeetCode——根据二叉树创建字符串与二叉树的最近公共祖先
LeetCode——根据二叉树创建字符串与二叉树的最近公共祖先
|
11月前
剑指offer 34. 二叉搜索树的后序遍历序列
剑指offer 34. 二叉搜索树的后序遍历序列
40 0