字符串可以看成是字符组成的数组。一般将把字符的ASII码作为标示来使用。
string s; 长度判断为s.length();
242.有效的字母异位词
题目描述:判断两个字符串包含的字符是否完全相同。
输入输出样例:输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。
Input: s="anagram", t="nagarm"
Output:true
题解:我们可以利用哈希表或数组统计两个数组中每个数字出现的频次,若频次相同,则说明它们包含的字符完全相同
bool isAnagram(string s, string t){
if(s.length() != t.length())){
return false;
}
vector<int> counts(26, 0); //初始化标记数组
for(int i=0; i<s.length(); ++i){
++count[s[i]-'a'];
--count[t[i]-'a'];
}
for(int i=0; i<count.size(); ++i){
if(count[i]){
return false;
}
}
return true;
}
205.同构字符串
题目描述:判断两个字符串是否同构。同构的定义是,可以通过把一个字符串的某些相同的字符转换成另一些相同的字符,使得两个字符串相同,
且两种不同的字符不能够被转换成同一字符。
输入输出样例:Input:s="paper", t="title" Output:true
在这个样例中,通过把s中的p,a,e,r字符转换成t,i,l,e字符,可以使得两个字符串相同。
题解:我们可以将问题转化一下:记录两个字符串每个位置的字符第一次出现的位置,如果两个字符串中相同位置的字符与它们第一次出现的位置
一样,那么这两个字符串同构。
bool isIsomorphic(string s, string t){
vector<int> s_first_index(256, 0), t_first_index(256, 0);
for(int i=0; i<s.length(); ++i){
if(s_first_index[s[i]] != t_first_index[t[i]]){ //妙
return false;
}
s_first_index[s[i]]=t_first_index[t[i]]=i+1; //记录位置信息
}
return true;
}
647.回文子串(Medium)
题目描述:给定一个字符,求“其有多少回文子字符串”。回文定义是从后往前读和从前往后读是一样的
输入输出样例:输入一个字符串,输出一个整数,表示回文字符串的数量。
Input:"aaa" Output:6 6个回文字符串分别是["a","a","a","aa","aa","aaa"]。
题解:我们可以从字符串的每个位置开始,向左向右延长,判断存在多少以当前位置为中轴的回文子字符串
int countSubstrings(string s){
int count=0;
for(int i=0; i<s.length();++i){
count += extendSubstrings(s, i, i); //奇数长度
count += extendSubstirngs(s, i, i+1); //偶数长度
}
return count;
}
int extendSubStrings(stirng s, int l, int r){ //头尾指针
int count = 0;
while(l >= 0 && r<s.length() && s[l] == s[r]){
--l;
++r;
++count;
}
return count;
}
28.实现strStr() 字符串匹配 人人都能看懂的kmp算法
题目描述:判断一个字符串是不是另一个字符串的子字符串,并返回其位置。
输入输出样例:输入一个母字符串,输出一个整数,表示子字符串在母字符串的位置,若不存在则返回-1。
Input:haystack="hello", needle="ll"
Output:2
题解:使用著名的Knuth-Morris-Pratt(KMP)算法,可以在O(m+n)时间利用动态规划完成匹配。
//主函数
int strStr(string haystack, string needle){
int k=-1, n=haystack.length(), p=needle.length();
if(p == 0) return 0;
vector<int> next(p, -1); //-1表示不存在相同的最大前缀和后缀
calNext(needle, next); //计算next数组
for(int i=0; i<n; ++i){
while(k>-1 && needle[k+1] !=haystack[i]){
k=next[k]; //有部分匹配,往前回溯
}
if(needle[k+1] == haystack[i]){
++k;
}
if(k == p-1){
return i-p+1; //说明k移动到needle的最末端,返回相应的位置
}
}
return -1;
}
//辅函数-计算next数组(前缀表) 最长相等前后缀
void calNext(const string &needle, vector<int> &next){
for(int j=1, p=-1; j<needle.length(); ++j){
while(p>-1 && needle[p+1]!=needle[j]){
p=next[p]; //如果下一位不同,往前回溯
}
if(needle[p+1] == needle[j]){
++p;
}
next[j]=p;
}
}
//暴力解法
int strStr(string haystack, string needle) {
if(!needle.length()) return 0;
for(int i=0;i<haystack.length();i++){
for(int j=0; j<needle.length();j++){
if(haystack[i+j]!=needle[j]) break;
if(j==needle.length()-1) return i;
}
}
return -1;
}
类型:
- 贪心算法
- 双指针
- 二分查找
- 排序算法
- 二维数组的搜索
- 动态规划
- 数据结构-stl
- 字符串比较、匹配
- 链表
- 二叉树