Leetcode 76. 最小覆盖子串

76. 最小覆盖子串

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:

如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

拿到这道题目,先分析,从字符串S中找出包含T所有字符的最小子串,意思就是如果S里有T,那么再从S的子串里面找T,如果S里面没有T的话,那么S的子串里也不可能有T了。从大窗口滑到小窗口还是有点复杂的,不如反过来,由小窗口滑到大窗口来的简单一点。从小窗口滑到大窗口的话,就是这样的,如果小窗口内不包含T,则right++,直到窗口内包含T为止,若当right到到S的末尾还没有,即S没有T,则可以返回"",如果小窗口内包含T,那么将这个窗口的子串以及该子串的长度保存,然后left++,右移这个窗口,然后重复判断包不包含T的这个流程,然后记录子串的最小值以及对应的子串。

while left <= s.length() - t.length() //窗口长度小于T的长度的时候必不可能存在满足条件的子串
    1 统计每个字符出现的次数
    2 子串不包含T
            right还未达到s的右边界
                right++
                right到达s的右边界
                    break
                调整子串以及各个字符出现的次数
                continue
      子串包含T
            left++
            记录长度最小的子串和该子串的长度
            调整子串以及各个字符出现的次数

总的来说核心的滑动窗口就是这样的了

public String minWindow(String s, String t) {
        int[] tdic = new int[128 - 65];
        int[] sdic = new int[128 - 65];
        char[] dic = t.toCharArray();
        String res = "";
        int len = 0x7fffffff;
        for (int i = 0; i < dic.length; i++) {
            tdic[dic[i] - 65]++;
        }
        sdic[s.charAt(0) - 65] = 1;
        int left = 0, right = 0;
        int mark = 0;
        int z = 0;
        if (s.length() < t.length())
            return "";
        if (s.equals(t))
            return s;
        StringBuilder sb = new StringBuilder();
        sb.append(s.charAt(left));
        while (left <= s.length() - t.length()) {
            mark = 0;
            for (int i = 0; i < sdic.length; i++) {
                if (tdic[i] > sdic[i]) {
                    mark = 1;
                    break;
                }
            }
            if (mark == 1) {
                if (right < s.length()) {
                    right++;
                    if (right == s.length())
                        break;
                    sb.append(s.charAt(right) );
                    sdic[s.charAt(right) - 65]++;
                    continue;
                }
            } else {
                left++;
                if(z++ == 0)
                    res = sb.length() < len ? sb.toString() : res;
                else
                    res = sb.length() < res.length() ? sb.toString() : res;
                sdic[s.charAt(left - 1) - 65]--;
                sb.delete(0, 1);
            }
        }
        return res;
    }

不过在时间上,花的时间就很久,滑动策略有待优化,。。。

和咸咸打卡的第五天 √

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值