LeetCode|Substring with Concatenation of All Words(所有单词的串联的子字符串)

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s"barfoothefoobarman"
words["foo", "bar"]

You should return the indices: [0,9].

(order does not matter).

都是C++代码。

思路:用两个map,第一个来记录字典里面的word以及出现的次数;第二个map用来实时记录更新给定字符串里面的情况。

我的思路就是然后从第一个字符向后遍历字典长度的子字符串。这种思路leetcode运行时间600ms左右。有点低效。但是很好想。

vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> res;
        int n=s.size();
        int num=words.size();
        int unit=words[0].size();
        if(words.size()==0||n<num*unit) return res;
        map<string,int> wordCount,check;
        for(int i=0;i<num;i++){
            ++wordCount[words[i]];
        }
        for(int i=0;i<=n-num*unit;i++){
            int count=0;//和num进行比较,如果一致则正确。(在每个word的次数一样前提下)
            check.clear();
            int start=i;
            string word=s.substr(i,unit);
            if(wordCount.find(word)==wordCount.end()) continue;
            for(int j=i;j<i+num*unit;j+=unit){
                if(j!=i) word=s.substr(j,unit);
                check[word]++;
                count++;
                
                if(check[word]>wordCount[word]){
                    break;
                }
                
                if(count==num){
                    res.push_back(start);
                }
            }
        }
        return res;
    }

其实上述解法存在重复的问题。是否能将之前检测的信息加以利用呢。后来借助酷壳网陈老师的思路,运行时间仅为60ms。

就是从头遍历到尾部,step为字典里面word的长度。如果出现word的出现次数,大于字典里面这个word的次数,就把最开始记录的word扫描,直到减去一次这个word。

    vector<int> findSubstring(string s, vector<string>& words) {//仅60ms时间,是我的十分之一。
        vector<int> res;
        int n=s.size();
        int num=words.size();
        int unit=words[0].size();
        if(words.size()==0||n<num*unit) return res;
        map<string,int> wordCount,check;
        for(int i=0;i<num;i++){
            ++wordCount[words[i]];
        }
        for(int i=0;i<unit;i++){
            int count=0;//和num进行比较,如果一致则正确。(在每个word的次数一样前提下)
            check.clear();
            int start=i;
            for(int j=i;j<n;j+=unit){
                string word=s.substr(j,unit);
                if(wordCount.find(word)==wordCount.end()){
                       check.clear();
                       start=j+unit;
                       count=0;
                       continue;
                }
                check[word]++;
                count++;
                if(check[word]>wordCount[word]){
                    string tmp;
                    do{
                        tmp=s.substr(start,unit);
                        --check[tmp];
                        --count;
                        start+=unit;
                    }while(tmp!=word);
                }
                
                if(count==num){
                    res.push_back(start);
                    string tmp=s.substr(start,unit);
                    start+=unit;
                    --check[tmp];
                    --count;
                }
            }
        }
        return res;
    }

总结bug:之间出现一些小问题,runtimen的提示:结果是手误,把wordCount这个map的赋值,出现i的范围过大;

start变量的step是unit,别忘了。很多小笔误困扰了好久。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值