LeetCode刷题——找到字符串中所有字母异位词

大家好,继续刷题,已经刷到了哈希表的部分,感觉这道题还是学到了很多,记录一下。

题目要求:

思路:1.我自己想的办法很笨,最终超时了,就是把s分成一个一个子字符串,然后跟p一起sort一下,然后看一不一样。代码如下:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> result;
        int len = s.size();
        int len_p = p.size();
        if(len == 0)
            return result;
        string temp;
        map<int,string> hash;
        for(int i = 0;i <= len - len_p;i++){
            temp = s.substr(i,len_p);
            hash.insert(pair<int,string> (i,temp));
            temp.clear();
        }
        map<int,string> :: iterator it = hash.begin();
        while(it != hash.end()){
            string t = it -> second;
            sort(t.begin(),t.end());
            sort(p.begin(),p.end());
            if(t == p){
                result.push_back(it -> first);
            }
            it++;
        }
        return result;
    }
};

2.然后去看了其他大大们写的代码,学习了很多,其中一种思想是获取s的子字符串然后计算里面字母的个数,比较跟p的字母个数是否一样就可以了,很巧妙,但这种思想也分两种办法,一种是用map来存放子字符串和p的字母及其个数,但是后续查看是否一样还需要遍历查找啊什么的就很麻烦,还有一种是用vector来存放子字符串和p的字母及其个数,vector相比map,使用起来就很灵活,速度也更快。代码如下。

map版:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int plen=p.size(),slen=s.size();
        vector<int> res;
        if(slen < plen) {return res;}
        map<char,int> mp;
        for(auto c:p) {
            mp[c]++;
        }
        for(int i=0;i<slen-plen+1;i++){
            map<char,int> temp;
            string substri=s.substr(i,plen);
            for(auto c:substri) temp[c]++;
            if(mapequal(temp,mp)) 
                res.push_back(i);
        }
        return res;
    }

    bool mapequal(map<char,int>& a,map<char,int>& b){
        if(a.size()!=b.size()) return false;
        map<char,int>::iterator iter;
        for(iter=a.begin(); iter!=a.end(); iter++){
            if(b.count(iter->first)==0||b[iter->first]!=iter->second)
                return false;
        }
        return true;
    }
};

vector版:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> pv(26,0), sv(26,0), res;
        if(s.size() < p.size())
           return res;
        for(int i = 0; i < p.size(); ++i)
        {
            ++pv[p[i]-'a'];
            ++sv[s[i]-'a'];
        }
        if(pv == sv)
           res.push_back(0);

        for(int i = p.size(); i < s.size(); ++i) 
        {
            ++sv[s[i]-'a'];
            --sv[s[i-p.size()]-'a']; 
            if(pv == sv)  
               res.push_back(i-p.size()+1);
        }
        return res;
    }
};

学到的东西有:

1.map的遍历:

for(iter=a.begin(); iter!=a.end(); iter++){
    if(b.count(iter->first)==0||b[iter->first]!=iter->second)
        return false;
    }

这里string::count()只是统计是否有字符,有就是返回1,无就是返回0。

2.for循环的用法:

for(auto c:s)//对于s中的每个字符

此处表示对s进行循环,c表示从0开始到len-1。

3.并不要盲目使用容器,最合适的才是最好的。

 

我们下期见。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值