zoukankan      html  css  js  c++  java
  • 【LeetCode】76. 最小覆盖子串(典型滑动窗口)

    题目链接

    https://leetcode-cn.com/problems/minimum-window-substring/

    题目描述

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

    示例:
    输入: S = "ADOBECODEBANC", T = "ABC"
    输出: "BANC"
    
    说明:
    如果 S 中不存这样的子串,则返回空字符串 ""。
    如果 S 中存在这样的子串,我们保证它是唯一的答案。

    解题思路

    1.暴力枚举

    双重for循环,从字符串S的每一个字符开始枚举,直到找到满足字符串T的子串,利用ans变量记录子串长度并进行迭代更新。

    2.滑动窗口

    标准的滑动窗口:

    1.把[left,right]称为一个窗口;
    2.先右移右指针扩大窗口,直到窗口中的数字满足字符串T数组要求;
    3.满足要求时,停止增加right,转而增加left缩小窗口,直到不满足要求.
    4.重复2,3步直到right走到字符串S的尽头。

    滑动窗口的模板:

    int left = 0, right = 0; //left right为双指针

    while (right < s.size())

    {

        window.add(s[right]);

        right++; //右移右指针扩大窗口

        while (valid) //直到窗口中的字符串满足字符串T的要求;

        {

            window.remove(s[left]); //满足要求时,停止增加right,转而增加left缩小窗口,直到不满足要求

            left++;

        }

    }

    这题对于我来说,难点在与valid条件的判断,采用

    if(window[s[r]] == mp[s[r]]) count++;
    if(count == mp.size())

    能够解决以下实例产生的问题:

    S = "BBBBCEAW"  T = "ABC"

    S = "bbaa"  T = "aba"

    AC代码

     1 class Solution {
     2 public:
     3     string minWindow(string s, string t) {
     4         if(t.size() > s.size()) return "";
     5         if(s == t) return t;
     6         map<char,int> mp;
     7         for(int i = 0; i < t.size(); i++) mp[t[i]]++;
     8         int l = 0;
     9         int r = 0;
    10         int count = 0;
    11         int len = INT_MAX;
    12         int start = -1;
    13         map<char,int>window;
    14         while(l <= r && r < s.size())
    15         {
    16             if(mp.count(s[r]) == 1)
    17             {
    18                 window[s[r]]++;
    19                 if(window[s[r]] == mp[s[r]]) count++;
    20             }
    21         
    22             if(count == mp.size()) //19行与22行代码就是对于valid条件的判断。
    23             {
    24                 while(l < r)
    25                 {
    26                     if(window.count(s[l]) == 0) l++;
    27                     else if(window[s[l]] == mp[s[l]]) break;
    28                     else if(window[s[l]] > mp[s[l]])
    29                     {
    30                         window[s[l]]--;
    31                         l++;
    32                     }
    33                 }
    34                 if(r-l+1 < len)
    35                 {
    36                     len = r-l+1;
    37                     start = l;
    38                 }
    39             }
    40             r++;
    41         }
    42         if(start != -1) return s.substr(start,len);
    43         else return "";
    44     }
    45 };
  • 相关阅读:
    《编写高质量代码》读书笔记
    IL,Emit之OpCodes说明(备查)
    每天进步一点点
    DOCTYPE 与浏览器模式分析[转]
    一个EL IF表达式引发的血案
    JVM系列文章
    SunOs设置环境变量
    Solaris系统查看进程与端口对应关系的命令
    jsp 报错调试
    vi命令提示:Terminal too wide
  • 原文地址:https://www.cnblogs.com/XDU-Lakers/p/12953051.html
Copyright © 2011-2022 走看看