344. 反转字符串
541. 反转字符串 II
剑指 Offer 05. 替换空格
用双指针法可以不用额外空间
我的解法:
string replaceSpace(string s) {
string X;
for (int i = 0; i < s.size(); i++)
{
if (s[i] != ' ')
X.push_back(s[i]);
else
{
X.push_back('%');
X.push_back('2');
X.push_back('0');
}
}
return X;
}
151. 颠倒字符串中的单词
先去除头尾的空格,对字符串进行反转
再以空格为分界 对每个单词进行反转
剑指 Offer 58 - II. 左旋转字符串
我的:
string reverseLeftWords(string s, int n) {
vector<char> x;
int index,i;
for ( i = 0; i < n; i++)
{
x.emplace_back(s[i]);
}
for (index = 0; index + n < s.size(); index++)
{
s[index] = s[index + n];
}
for (i=0; index < s.size(); index++)
{
s[index] = x[i++];
}
return s;
}
参考:不申请额外空间
class Solution {
public:
string reverseLeftWords(string s, int n) {
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
reverse(s.begin(), s.end());
return s;
}
};
KMP算法
由来:由这三位学者发明的:Knuth,Morris和Pratt,所以取了三位学者名字的首字母。所以叫做KMP
用途:KMP主要应用在字符串匹配上。
KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。
用法:
求出模式串的前缀表 ,确定回退到的位置
前缀表求法:
vector<int> getNext(string s){
int len = static_cast<int> (s.size());
vector<int> next(len,0);
int i;
int j = 0;
for (i = 1; i < s.length(); i++){
while (j > 0 && s[i] != s[j]) { // j要保证大于0,因为下面有取j-1作为数组下标的操作
j = next[j - 1]; // 注意这里,是要找前一位的对应的回退位置了
}
if (s[i] == s[j]) {
j++;
}
next[i] = j;
}
return next;
}
kmp算法:
int strStr(string haystack, string needle) {
if (needle.size() == 0)
return 0;
int len1, len2;
len1 = haystack.size();
len2 = needle.size();
int i, j;
vector<int> next;
next = getNext(needle);
j = 0;
for (i = 0; i < len1; i++){
cout << haystack[i] << " " << needle[j] << endl;
while (j > 0 && haystack[i] != needle[j]) {
j = next[j - 1];
}
if (haystack[i] == needle[j]) {
j++;
}
if (j ==len2 ) {
return (i - len2 + 1);
}
}
return -1;
}
28. 实现 strStr()
459. 重复的子字符串
如果一个字符串可以由字字符串组成
数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。