算法18.0

76. 最小覆盖子串 - 力扣(LeetCode)

审题要理解清楚

解法1:

依旧暴力解法

枚举所有的情况 然后找到那个长度最小的字符串

解法2:优化暴力解法

这道题的算法原理有点类似算法14.0的思路 构建两个哈希表然后维护count

为了不失一般性 依旧一条横线表示题目的情况

我们找到一个区间符合情况后 开始考虑其他遍历情况(也就是双指针的移动情况)

当left右移一步 right需不需要回来再走一次

这个时候需要分情况讨论了 如果没移动前的left的那个位置的元素的个数大于hash1里面

说明这个时候 移动了也没有问题 right不需要回来再走一次

如果刚刚够或者小于 那么移动了会影响 right也没有必要回来再走一次 直接right++ 去加入新的i情况

这个时候发现 left和right都往一个方向走 联想到滑动窗口

思考滑动窗口的具体步骤不清晰的时候 可以尝试以暴力解法起手去尝试着寻找思路

判断:hash2的有效字符大于等于hash1的时候 才出窗口

优化:判断的时候 check

用变量标记一下有效字符的个数 但是这个和算法14.0中count的意义是不一样的

这里的count是比较的有效字符的种类

如果统计的是有效字符的个数的话语 是不行的 详情看下图

具体怎么统计种类 还是在进窗口和出窗口的时候维护

细节问题:

维护count的时候 发现不能用数组来维护

所以用一个新的变量kinds 表示字符的种数

解法3:类似使用算法14.0的思路

下面是题目、效果图和代码:

java 复制代码
class Solution {
    public String minWindow(String ss, String tt) {
        char[] s = ss.toCharArray();
        char[] t = tt.toCharArray();

        int[] hash1 = new int[128];
        int kinds = 0;
        for(char ch:t) {//统计t里面的频次 并找出了有多少种字符
        //    if(hash1[ch] == 0) kinds++;
        //    hash1[ch]++;
           if(hash1[ch]++ == 0) kinds++;
        }
        
        int[] hash2 = new int[128];//用来统计窗口中字符出现的频次
        int minlen = Integer.MAX_VALUE , begin = -1;
        for(int left=0,right=0,count =0;right<s.length;right++){
            
            char in = s[right];

            // hash2[in]++; 
            // if(hash2[in]==hash1[in]) count++;//如果hash1和hash2 说明我们加入了一个有效字符
             // //进窗口+维护count
            if(++hash2[in]==hash1[in]) count++; //上面两行代码可以简化成这一行 哈哈
            while(kinds==count){//判断
             //更新结果
             if(right-left+1<minlen){
                begin = left;
                minlen=right-left+1;
             }
             char out = s[left++];//移除窗口的时候记得移动一位
            //  if(hash2[out] == hash1[out]) count--;
            //  hash2[out]--;
             if(hash2[out]-- == hash1[out]) count--;//出窗口+维护count
            }
        }
        if(begin == -1) return new String();
        else return ss.substring(begin,begin+minlen);
    }
}
//xiyu251024&1#2*8
相关推荐
码农多耕地呗3 小时前
力扣543.二叉树的直径(java)(迭代法 and 左右根后序遍历迭代法)
算法·leetcode·职场和发展
努力学习的小廉4 小时前
我爱学算法之—— 分治-归并
c++·算法·1024程序员节
Gorgous—l4 小时前
数据结构算法学习:LeetCode热题100-链表篇(下)(随机链表的复制、排序链表、合并 K 个升序链表、LRU 缓存)
数据结构·学习·算法
仰泳的熊猫4 小时前
LeetCode:200. 岛屿数量
数据结构·c++·算法·leetcode
流星5211224 小时前
GC 如何判断对象该回收?从可达性分析到回收时机的关键逻辑
java·jvm·笔记·学习·算法
defaulter4 小时前
Codeforces Round 1049 (Div. 2)C. Ultimate Value
算法·codeforces
让我们一起加油好吗4 小时前
【数论】费马小定理
c++·算法·数论·1024程序员节·费马小定理·逆元
大数据张老师5 小时前
数据结构——冒泡排序
数据结构·算法·排序算法·1024程序员节
m0_748233645 小时前
单调队列【C/C++】
c语言·c++·算法·1024程序员节