代码随想录算法训练营第十天| LeetCode459.重复的子字符串

459.重复的子字符串

题目:459. 重复的子字符串

// //暴力解法超时O(N^2),需要剪枝操作
class Solution {
public:
    bool isrepeat(string& s, string& son){
        for(int j = 0; j < s.size(); j += son.size()){
            int k = 0;
            while(k < son.size()){
                if(s[j+k] != son[k]) return false;
                ++k;
            }
        }
        return true;
    }
    bool repeatedSubstringPattern(string s) {
        for(int i = 1; i <= s.size() / 2; ++i){   //只需要循环主串的一半位置
            //i是子串的结束位置
            string son = s.substr(0,i);
            //cout << son << endl;
            if(isrepeat(s,son)) return true;
        }
        return false;
    }
};
//移动匹配O(n)
//如果是由重复子串组成的,主串长度减去最长相等前后缀长度,就是重复子串长度
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        //如果符合要求,s+s一定包含s
        string ss = (s + s).substr(1,s.size() * 2 - 2);
        //string ss = s + s;
        //ss.erase(ss.begin());ss.erase(ss.end() - 1);//这样删除也可以O(n)
        if(ss.find(s) != string::npos) return true;//O(n)
        else return false;
    }
};
//KMP
class Solution {
public:
    void getNext(int *next, string &s){
        int j = 0;
        next[0] = 0;
        for(int i = 1; i < s.size(); ++i){
            while(j > 0 && s[i] != s[j]){
                j = next[j - 1];
            }
            if(s[i] == s[j]){
                j++;
            }
            next[i] = j;
        }
    }
    bool repeatedSubstringPattern(string s) {
        //if(s.size(() == 0) return false;
        int next[s.size()];
        getNext(next,s);
        int son_len = s.size() - next[s.size() - 1];
        if(next[s.size() - 1] != 0 && s.size() % son_len == 0) return true;
        return false;
    }
};

总结

字符串:反转,双指针,KMP找子串

双指针法展现出效率的优势:通过两个指针在一个for循环下完成两个for循环的工作

你可能感兴趣的:(代码随想录算法训练营,算法,leetcode,字符串,KMP)