前言
这是七月集训的第2日,今日的训练内容是 字符串
解题报告
1.力扣2315
原题链接
题目概述
给你一个字符串 s ,每 两个 连续竖线 ‘|’ 为 一对 。换言之,第一个和第二个 ‘|’ 为一对,第三个和第四个 ‘|’ 为一对,以此类推。
请你返回 不在 竖线对之间,s 中 ‘*’ 的数目。
注意,每个竖线 ‘|’ 都会 恰好 属于一个对。
解题思路
用一个栈记录一下 ‘|’ 的数量就可以了。
源码剖析
int countAsterisks(char * s){
int len = strlen(s);
int stack = 0;
int ans = 0;
int i;
for(i = 0;i<len;++i){
if(s[i]=='|'&&stack==0){
stack++;
continue;
}
if(s[i]=='|'&&stack!=0){
stack--;
continue;
}
if(stack==0&&s[i]=='*'){
ans++;
}
}
return ans;
}
2.力扣459
原题链接
题目概述
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
解题思路
这题之前有做过类似的题目,使用了比较暴力的算法进行枚举,这次学习了官解的思路:如果一个字符串是满足条件的子串,那么把这个子串从头去掉,然后再加到字符串的尾部,这个字符串和原来仍然相同。这是主要思路,然后由这个思路通过一系列的证明可以证明:如果把原来的字符串 s 接在本身的后面,然后去除第一个和最后一个字符之后 s 是新字符串的子串,那么就可以得出原来的字符串是满足条件的。
同时这里使用了strtsr(a,b);
函数,也作积累,是用于在 a 中找到 b 第一次出现的位置
源码剖析
bool repeatedSubstringPattern(char* s) {
int n = strlen(s);
char k[2 * n + 1];
k[0] = 0;
strcat(k, s);
strcat(k, s);
return strstr(k + 1, s) - k != n;
}
3.力扣1790
原题链接
题目概述
给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。
如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。
解题思路
一开始把这题想的过于简单了,实际上要满足各种刁钻的不同情况的字符串的话,需要满足两个条件:首先两个字符串中不同的字符的数目不可以超过 2 组,这里使用一个栈就可以了。
接下来是,不同的那些字符串的字母一定要是相同的,这里我使用了两层判断来确认不同部分的字符串是否相等。第一层是先将不一样的字符串塞到哈希表中,所有字母出现的次数都应该是偶数次,接下来,两个字符串不同部分的字符只需要 ascii 码也相同,就必定是一样的了。
源码剖析
bool areAlmostEqual(char * s1, char * s2){
int hash[26]={0};
int len = strlen(s1);
int i;
int stack = 0;
int stack1=0,stack2=0;
for(i=0;i<len;++i){
if(s1[i]!=s2[i]){
stack++;
stack1+=s1[i];
stack2+=s2[i];
hash[s1[i]-'a']++;
hash[s2[i]-'a']++;
if(stack>2) return false;
}else{
continue;
}
}
for(i = 0;i<26;++i){
if(hash[i]&1)
return false;
}
if(stack1!=stack2) return false;
return true;
}
4.力扣1961
原题链接
题目概述
给你一个字符串 s 和一个字符串数组 words ,请你判断 s 是否为 words 的 前缀字符串 。
字符串 s 要成为 words 的 前缀字符串 ,需要满足:s 可以由 words 中的前 k(k 为 正数 )个字符串按顺序相连得到,且 k 不超过 words.length 。
如果 s 是 words 的 前缀字符串 ,返回 true ;否则,返回 false 。
解题思路
直接遍历然后注意移动下标就可以了。
源码剖析
bool isPrefixString(char * s, char ** words, int wordsSize){
int len = strlen(s);
int i,j=0,k=0;
for(i=0;i<len;++i){
if(j>=wordsSize) return false;
if(s[i]==words[j][k]){
if(words[j][k+1]==NULL){
j++;
k=0;
continue;
}else{
k++;
continue;
}
}else return false;
}
if(s[i]!=NULL||k!=0) return false;
return true;
}