class Solution {
public:
string reverseWords(string s) {
int read=0,write=0,len=0;
reverse(s.begin(),s.end());
while(s[read]==' '){
read++;
}
while(read<s.size()){
while(read<s.size()&&(s[read]!=' ')){
len++;
read++;
}
for(int i=1;i<=len&&(read-i)>(write+i-1);i++){
int tmp;
tmp=s[write+i-1];
s[write+i-1]=s[read-i];
s[read-i]=tmp;
}
write+=len+1;
len=0;
while(read<s.size()&&s[read]==' '){
read++;
}
}
s.resize(write-1);
return s;
}
};
将字符串整体翻转一次后,逐词翻转,去除多余空格的需求也可以借助一下双指针的思想。
#include<iostream>
using namespace std;
int main(){
int n;
string s;
cin >> n >> s;
int tmp[n];
for(int i=0;i<n;tmp[n-1-i]=s[s.size()-1-i],i++);
for(int i=s.size()-1-n;i>=0;s[i+n]=s[i],i--);
for(int i=0;i<n;s[i]=tmp[i],i++);
cout << s;
return 0;
}
同样可以借助双指针。
class Solution {
public:
int strStr(string haystack, string needle){
if(needle.size()<=haystack.size()){
int next[needle.size()];
next[0]=0;
if(needle.size()>1){
next[1]=0;
}
for(int i=2;i<needle.size();i++){
if(needle[next[i-1]]==needle[i-1]){
next[i]=next[i-1]+1;
}else{
int j;
for(j=next[i-1];needle[next[j]]!=needle[i-1]&&next[j]!=0;j=next[j]);
if(needle[next[j]]==needle[i-1]){
next[i]=next[j]+1;
}else{
next[i]=0;
}
}
}
int i,j;
for(i=0,j=0;i<haystack.size();){
if(haystack[i]==needle[j]){
j++;
i++;
}else{
if(j!=0){
j=next[j];
}else{
i++;
}
}
if(j==needle.size()){
return i-needle.size();
}
}
}
return -1;
}
};
笔者仿照的博客计算的前缀表稍稍有些不同,不过本质上只是整体向右位移一位,最左侧补0。求取的前缀表中数值在代码中的意义是,在比对过程中,needle字符串中下标为i的字符比对结果为不同时,将i令为next[i]再进行比对,直到找到比对结果相同的i或i到了0。
https://www.cnblogs.com/aninock/p/13796006.html
next[i]的值是索引i以前字符串中最长的公共前后缀的长度,这个模式串既与s[0]到s[next[i]-1]的部分相同,又与s[i-next[i]]到s[i-1]的部分相同。next的求取过程笔者仍处在心里明白但组织不出足够凝练精准的语言,姑且先不产生有害信息了。
class Solution {
public:
bool repeatedSubstringPattern(string s) {
if(s.size()<2){
return false;
}
int next[s.size()+1];
next[0]=0;
next[1]=0;
for(int i=2;i<s.size()+1;i++){
if(s[next[i-1]]==s[i-1]){
next[i]=next[i-1]+1;
}else{
int j;
for(j=next[i-1];s[next[j]]!=s[i-1]&&next[j]!=0;j=next[j]);
if(s[next[j]]==s[i-1]){
next[i]=next[j]+1;
}else{
next[i]=0;
}
}
}
int max=1;
for(int i : next){
if(i>max){
max=i;
}
}
if(s.size()%(s.size()-next[s.size()])!=0||next[s.size()]!=max){
return false;
}
return true;
}
};
这是代码随想录的解释,笔者自己刚刚搞当一个字符串可以由重复的子字符产生时KMP算法得到的前缀表为什么会产生一定的特性,但由这个特性为什么就能倒推到字符串可由重复的子字符串组成,还是有疑惑。