26 重复的子字符串
给定一个非空的字符串 s
,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba"
输出: false
示例 3:
输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
解法一:暴力
两层循环,i为子串长度,j起始值为第二次匹配的位置,即i
举个例子 ababab
当i=2时,s[2]=s[0],s[3]=s[1],s[4]=s[2],s[5]=s[3]
即满足s[j]=s[j-i]
cs
bool repeatedSubstringPattern(char* s) {
int n=strlen(s);
bool flag=false;
//遍历子串字符 i为子串长度
for(int i=1;i<=n/2;i++){
if(n%i==0){
flag=true;
for(int j=i;j<n;j++){
if(s[j]!=s[j-i]){
flag=false;
break;
}
}
if(flag)return true;
}
}
return false;
}
解法二:KMP算法
next数组从0开始,next数组求解
子串为最长相等前后缀(next[n-1])所不包含的串,n为数组长度
如果n可以整除n-next[n-1]并且next[n-1]!=0,说明是由重复子串构成的。
例如ababab
next数组为0 0 1 2 3 4,不包含的串长度为2即为子串
6%(6-4)==0,满足题意
例如aba
next数组为0 0 1 ,不包含的串长度为2即为子串。但是3%2!=0,不满足题意
如果是abab呢,next为 0 0 1 2,不包含的串长度为2即为子串。4%2!=0,满足题意
cs
bool repeatedSubstringPattern(char* s) {
int n=strlen(s);
bool flag=false;
int *next=(int *)malloc(sizeof(int)*(n+1));
next[0]=0;
for(int i=1,j=0;i<n;i++){
while(j>0&&s[i]!=s[j])j=next[j-1];
if(s[i]==s[j])j++;
next[i]=j;
}
//子串为最长相等前后缀所不包含的串
if(n%(n-next[n-1])==0&&next[n-1]!=0)return true;
else return false;
}
右旋字符串(第八期模拟笔试)
题目描述
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。
输入描述
输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。
输出描述
输出共一行,为进行了右旋转操作后的字符串。
输入示例
2
abcdefg
输出示例
fgabcde
提示信息
数据范围:
1 <= k < 10000,
1 <= s.length < 10000;
k把字符串划分为两部分
1、字符串全部翻转
2、两部分分别翻转
cs
#include<stdio.h>
#include<string.h>
void Sol(char s[],int start,int end){
int tem;
for(int i=start,j=end;i<=j;i++,j--){
tem=s[i];
s[i]=s[j];
s[j]=tem;
}
}
int main(){
int k;
scanf("%d",&k);
char s[10005]={};
scanf("%s",s);
int len=strlen(s);
Sol(s,0,len-1);
Sol(s,0,k-1);
Sol(s,k,len-1);
for(int i=0;i<len;i++){
printf("%c",s[i]);
}
}