LeetCode/数青蛙

发布时间 2023-05-06 04:27:06作者: 失控D大白兔

请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目

1. 回溯+标记

每一趟跑一个青蛙(超时)
class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        int n =croakOfFrogs.size();
        string pattern = "croak";
        if(n%pattern.size()!=0) return -1;
        vector<bool> visit(n);
        int count = 0;
        for(int i=0;i<n;i++){
            if(!visit[i]&&croakOfFrogs[i]==pattern[0]){
                if(backtrack(croakOfFrogs,pattern,visit,i)==0) return -1;
                count++;
            }
        }
        return count;
    }
    bool backtrack(string& s,string &pattern,vector<bool>&visit,int i){
        if(i==s.size()) return true;
        int j = 0;
        while(i<s.size()&&j<pattern.size()){
            if(!visit[i]&&s[i]==pattern[j]){
                visit[i] = true;
                i++;
                j++;
            }
            else i++;
        }
        if(j==pattern.size()){//当前匹配完毕
            return backtrack(s,pattern,visit,i);
        }
        if(j==0) return true;//该青蛙终止
        return false;//没叫完
    }
};

2. 循环队列

一趟跑一只青蛙(超时)
class Solution {
public:
    int minNumberOfFrogs(string mainstr) {
        int n = mainstr.size();
        string pattern = "croak";
        if(n%pattern.size()!=0) return -1;
        int count = 0;
        queue<char> q;
        for(int i=0;i<n;i++)
            q.push(mainstr[i]);
        int index = 0;//匹配串指针,循环移动
        while(!q.empty()){
            int len = q.size();
            if(q.front()!=pattern[0]) return -1;//第一个字符必须与模板串相同
            count++;//一趟青蛙叫
            for(int i=0;i<len;i++){
                char c = q.front();
                q.pop();
                if(c==pattern[index]){
                    index = (index + 1)%pattern.size();
                }
                else q.push(c);//送到第二轮
            }
            if(index!=0) return -1;//必须完全匹配
        }
        return count;
    }
};

3. 哈希计数

记录上一个状态的数量,以此转移到下一个状态

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        int n = croakOfFrogs.size();
        if(n%5!=0) return -1;
        map<char,char> pre;
        const string croak = "croakc";
        for (int i = 1; i < croak.size(); i++)
            pre[croak[i]] = croak[i - 1];

        map<char,int> cnt;
        for (char &ch: croakOfFrogs) {
            char pr = pre[ch]; // pre 为 ch 在 "croak" 中的上一个字母
            if (cnt[pr]) // 如果有青蛙发出了 pre 的声音
                cnt[pr]--; // 复用一只
            else if (ch != 'c') // 否则青蛙必须从 'c' 开始蛙鸣
                return -1; // 不符合要求
            cnt[ch]++; // 发出了 ch 的声音
        }
        if (cnt['c'] || cnt['r'] || cnt['o'] || cnt['a'])
            return -1; // 有发出其它声音的青蛙,不符合要求
        return cnt['k']; // 最后青蛙们都发出了 'k' 的声音
    }
};