leetcode
3.无重复字符的最长子串
题目链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
时间复杂度:O(N)
空间复杂度:O(N)
题解:
int lengthOfLongestSubstring(string s) {
if(s.size()==0) return 0;
unordered_set<char> lookup;
int left=0;
int maxNum=0;
for(int i=0;i<s.length();i++){
while(lookup.find(s[i])!=lookup.end()){
lookup.erase(s[left]);
left++;
}
maxNum=std::max(maxNum,i-left+1);
lookup.insert(s[i]);
}
return maxNum;
}
76. 最小覆盖子串
题目链接:https://leetcode-cn.com/problems/minimum-window-substring/
时间复杂度:O(|S|+|T|)
空间复杂度:O(|S|+|T|)
题解:
string minWindow(string s, string t) {
if(t.length()>s.length() || s.length()==0) return "";
int left=0;
int distance=0;
int minNum=s.length()+1;
int begin=0;
unordered_map<char,int> winFreq;
unordered_map<char,int> tFreq;
for(int i=0;i<t.length();i++){
tFreq[t[i]]++;
}
for(int i=0;i<s.length();i++){
// std::cout<<winFreq[s[i]]<<":::"<<tFreq[s[i]]<<std::endl;
if(winFreq[s[i]]<tFreq[s[i]]){
distance++;
}
winFreq[s[i]]++;
while(distance==t.length()){
if(winFreq[s[left]]==tFreq[s[left]]){
if(minNum>i-left+1){
minNum=i-left+1;
begin=left;
}
distance--;
}
winFreq[s[left]]--;
left++;
}
}
if(minNum==s.length()+1) return "";
return s.substr(begin,minNum);
}
引入了一个distance变量来比较窗口中的字符串是否和目标字符串对应的字符个数相等,这样就把比较的操作时间复杂度降到O(1),这是一种加法的思想,要维护distance需要两个准则:
- 在窗口边界右移时,窗口中该字符个数小于目标字符串中该字符的个数时,distance才加1
- 当窗口边界左移时,窗口中该字符个数等于目标字符串中该字符的个数时,distance才减1
这就保证了,distance能够准确反映窗口中字符和目标字符串字符的匹配程度。
209. 长度最小的子数组
题目链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum/
时间复杂度:O(N)
空间复杂度:O(N)
int minSubArrayLen(int s, vector<int>& nums) {
int minNum=nums.size()+1;
int sum=0;
int left=0;
for(int i=0;i<nums.size();i++){
sum+=nums[i];
// std::cout<<sum<<std::endl;
while(sum>=s){
// std::cout<<"minNum="<<minNum<<",i-left+1="<<i-left+1<<std::endl;
minNum=std::min(minNum,i-left+1);
sum-=nums[left];
left++;
// std::cout<<"in::"<<sum<<std::endl;
}
}
if(minNum==nums.size()+1) return 0;
return minNum;
}
相对前两道,很简单了,就是两个边界移吖移。
//TODO 待更新