151.反转字符串中的单词
class Solution {
public:
void removeExtraSpaces(string &s) {
int slow = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] != ' ') {
if(slow != 0) {
s[slow++] = ' ';
}
while (i <= s.size() - 1 && s[i] != ' '){
s[slow++] = s[i++];
}
}
}
s.resize(slow);
}
void reverse(string &s, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
swap(s[i],s[j]);
}
}
string reverseWords(string s) {
removeExtraSpaces(s);
reverse(s, 0, s.size()-1);
int start = 0;
for(int i = 0; i <= s.size(); i++) {
if(i == s.size() || s[i] == ' ') {
reverse(s,start, i - 1);
start = i+1;
}
}
return s;
}
};
55.右旋字符
using namespace std;
#include<iostream>
#include<algorithm>
int main() {
int n;
string s;
cin >> n;
cin >> s;
reverse(s.begin(), s.end());
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
cout << s << endl;
return 0;
}
28.找出字符串找那个第一个匹配的下标
题目链接:28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)
class Solution {
public:
void getNext(vector<int>& next, string& s) {
int j = 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;
}
}
int strStr(string haystack, string needle) {
vector<int> next(needle.size());
next[0] = 0;
getNext(next, needle);
int j = 0;
for (int i = 0; i < haystack.size(); i++) {
while (j > 0 && haystack[i] != needle[j]) {
j = next[j - 1];
}
if (haystack[i] == needle[j]) {
j++;
}
if (j == needle.size()) {
return i - needle.size() + 1;
}
}
return -1;
}
};
这里的顺序得是
-
先处理不匹配的情况(回退
j),避免无效匹配。 -
再处理匹配的情况(
j++),推进匹配进度。 -
最后记录
next[i],确保计算正确。
459.重复的子串
题目链接:459. 重复的子字符串 - 力扣(LeetCode)
class Solution { // 暴力解法
public:
bool repeatedSubstringPattern(string s) {
int n = s.size();
int j = 0;
bool match;
for (int i = 1; 2 * i <= n; i++) {
for (int j = i; j < n; j++) {
if (n % i == 0) {
match = true;
if (s[j] != s[j - i]){
match = false;
break;
}
}
}
if (match)
return true;
}
return false;
}
};
看s能否由长度为1,2,3...n/2个字符组成
s[j] == s[j - i] 是为了验证字符串是否具有周期性,即能否由长度为 i 的子串重复构成。
j就直接从i开始,如果从0开始,一是没有必要,二是会访问到【0-i】会是负数
class Solution {//移动匹配算法
public:
bool repeatedSubstringPattern(string s) {
return (s+s).find(s,1) != s.size();
}
};
我靠,这个思路有点太牛了,就是把字符串拼接起来,如果字符串有子串,中间就能找到这个字符串
但如果是abc abc,就找
【1,3】:bca
【2,4】:cab
【3,5】:abc就等于s.size()了,返回false,就很妙
class Solution {//KMP算法
public:
void getNext(vector<int>& next, const string& s) {
next[0] = 0;
int j = 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;
vector<int> next(s.size());
getNext(next, s);
int len = s.size();
if (next[len - 1] != 0 && len % (len - next[len - 1]) == 0){
return true;
} // 必须要next[len - 1] != 0,因为如果没有相同前后缀肯定也没有相同子串构成
return false;
}
};
字符串算法题解析:反转、匹配与重复子串
888

被折叠的 条评论
为什么被折叠?



