> 文档中心 > LeetCode76-最小覆盖子串:滑动窗口(Cpp+Golang)

LeetCode76-最小覆盖子串:滑动窗口(Cpp+Golang)


题目链接:LeetCode76


题意

        给定两个字符串s和t,求s中最小的子串,使得该子串包含t中所有的字符。

        子串:字符串中连续的区间组成的字符串。

题解

  • 最小连续区间滑动窗口!冲!
  • 用一个map:mpt保存字符串t中的所有字符的出现情况
  • 用一个map:mps保存当前窗口所有字符的出现情况
  • 对于每一个窗口,用check函数判定其窗口可用性
    • check函数,比较两个map的值,只有当mpt中的所有键对应值严格等于mps中所有键的对应值时候,才是一个合理有效的窗口。
  • 虽然技术上确实是一个滑动窗口,但是验证check函数比较暴力,所有复杂度略高,Cpp实现过程中,需要使用unordered_map,不然会超时。

代码(Golang)

func minWindow(s string, t string) string {    mps,mpt:=make(map[byte]int),make(map[byte]int)    for i:=range t{ mpt[t[i]]++    }    ansL,ll,l,r:=-1,math.MaxInt64,0,0    check:=func()bool{ for k,v:=range mpt{     if mps[k]<v{  return false     } } return true    }    for ;r<len(s);r++{ if r0{     mps[s[r]]++ } for check()&& l<=r{     if r-l+10{  mps[s[l]]--     }     l++ }    }    if ll==math.MaxInt64{ return ""    }    return s[ansL:ansL+ll]}

代码(Cpp)

class Solution {public:    #define len(s) s.size()    unordered_mapmp,mpp;    bool check(){ for(auto i:mp){     if(mpp[i.first]<i.second){     // cout<<i.first<<" "<<i.second<r;r++){     if(r0){  mpp[s[r]]++;     }   while(check()&&(l<=r)){  if(r-l+10){      mpp[s[l]]--;      //cout<<l<<" "<<r<<" "<<s[l]<<endl;  }  l++;  //cout<<l<<' '<<r<<endl;     } } if (ansL==-1)return ""; //cout<<ansL<<' '<<len<<' '<<r; return s.substr(ansL,len);    }};

说说控