【LeetCode】 子字符串思路

本文介绍如何使用vector<int> map数据结构解决多种字符串子串问题,包括最短给定子串、最长可出现两次子串及最长无重复子串等。通过具体实例和代码模板,展示map在不同子串问题中的灵活应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一些求字串含有固定字符最短串,含有不同字符最长子串等问题中,利用 vector<int> map(128, 0)可以解决

题一:最短给定子串

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string "".
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
Seen this question in a real interview before?

思路:

利用map,将常用的128个ascall码都包含进去,然后将T里有的字符在map进行累加,并计数,然后在S里找子串,完全找到后计数为零,然后继续找,直到找到最短的子串。

class Solution {
public:
    string minWindow(string s, string t) {
        vector<int> map(128,0);
        int counter=t.size(), begin=0, end=0, min_length=INT_MAX, head = 0;
        for(auto a : t) map[a]++;
        while(end<s.size()){
            if(map[s[end++]]-- > 0) counter--;
            while(counter == 0){
                if(min_length > end - begin) min_length = end - (head = begin); 
                if(map[s[begin++]]++ == 0) counter++;                
            } 
        }
        return min_length == INT_MAX ? "" : s.substr(head, min_length);
    }
};

 

模板

int findSubstring(string s){
        vector<int> map(128,0);
        int counter; // check whether the substring is valid
        int begin=0, end=0; //two pointers, one point to tail and one  head
        int d; //the length of substring

        for() { /* initialize the hash map here */ }

        while(end<s.size()){

            if(map[s[end++]]-- ?){  /* modify counter here */ }

            while(/* counter condition */){ 
                 
                 /* update d here if finding minimum*/

                //increase begin to make it invalid/valid again
                
                if(map[s[begin++]]++ ?){ /*modify counter here*/ }
            }  

            /* update d here if finding maximum*/
        }
        return d;
  }

根据模板就可以在不同的子串题中进行应用,也不是为了死搬硬套,这个只是利用map解决的思路,像递归解决排列问题一样。

题二:最长可出现两次子串

int lengthOfLongestSubstringTwoDistinct(string s) {
        vector<int> map(128, 0);
        int counter=0, begin=0, end=0, d=0; 
        while(end<s.size()){
            if(map[s[end++]]++==0) counter++;
            while(counter>2) if(map[s[begin++]]--==1) counter--;
            d=max(d, end-begin);
        }
        return d;
    }

题三:最长无重复子串‘

输出长度

int lengthOfLongestSubstring(string s) {
        vector<int> map(128,0);
        int counter=0, begin=0, end=0, d=0; 
        while(end<s.size()){
            if(map[s[end++]]++>0) counter++; 
            while(counter>0) if(map[s[begin++]]-->1) counter--;
            d=max(d, end-begin); //while valid, update d
        }
        return d;
    }

输出具体子串,这里加一个子串起始标志位就行,在更新长度时更新子串起始位就行

 

转载于:https://www.cnblogs.com/ygh1229/p/9830132.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值