字符串面试题的特点:
- 、广泛性(可以把字符串看做字符类型的数组)所以与数组的排序、查找和调整有关
- 、需要掌握的概念 (回文、子串(连续)、子序列(不连续)、前缀树(Trie树)、后缀树和后缀数组、匹配、字典序)
- 、需要掌握的操作(与数组有关的操作:增删改查、字符串替换、字符串旋转)
- 字符串题目的常见类型
1.规则判断(判断是否符合整数规则、判断字符串是否符合浮点数规则、是否符合回文字符串规则)
2.数字运算(int long类型表达整数范围有限所以经常用字符串实现大整数)
3.与数组操作有关的类型(调整、排序)
4.字符计数(可用哈希表、固定长度的数组)
一、给定两个字符串str1和str2,如果str1和str2中出现的字符种类一样且每种字符出现的次数也一样,那么str1与str2互为变型词。
实现一个函数判断两个字符串是否互为变型词
思路:使用哈希表做字计数
int chkTransfrom(char *str1, char *str2)
{
if(str1==NULL || str2==NULL)
{
return -1;
}
int len1 = strlen(str1);
int len2 = strlen(str2);
if(len1 != len2)
{
return -1;
}
int hash[256];
int i = 0;
memset(hash, 0 , sizeof(hash));
for(i=0; i<len1; i++)
{
/*字符作为key, 字符出现的次数作为value*/
hash[str1[i]]++;
}
for(i=0; i<len2; i++)
{
/*如果还没--之前就等于0则说明这个字符在数组中的(这个位置str[i])个数为0,证明前面的字符串中没有这个字符*/
if(hash[str2[i]]-- == 0)
return -1;
}
return 0;
}
二、给定一个字符串str,将其中所有空格字符替换成"%20",假设str后面有足够的空间
思路:1、先遍历字符串,找出空格数量,然后计算出替换后的长度。
2、然后从最后(替换后的长度的最后)把原来长度的字符一 一对应的填到相应的位置,遇到空格就填 ‘0’、‘2’、‘%’
3、直到索引j == i就退出(证明空格已经全部替换完成了)
char *replaceSpace(char *str)
{
if(str == NULL)
{
return str;
}
int len1 = strlen(str);
int space = 0;
int i;
for(i=0; i<len1; i++)
{
if(str[i] == ' ')
{
space++;
}
}
int j = len1 + 2 * space - 1;
i = len1 - 1;
while(j != i)
{
if(str[i] == ' ')
{
str[j--] = '0';
str[j--] = '2';
str[j--] = '%';
}
else
{
str[j--] = str[i];
}
i--;
}
return str;
}
三、给定一个字符串str,判断是不是整体有效的括号字符串
int judge(char *str)
{
if(str == NULL)
{
return str;
}
int len = strlen(str);
int i = 0;
int count = 0;
for(i=0; i<len; i++)
{
if(str[i] == '(')
{
count++;
}
else if(str[i] == ')' && --count < 0)
{
return 0;
}
else if(str[i] != '(' && str[i] != ')')
{
return 0;
}
}
return count == 0;
}
*****************四、给定一个字符串str返回str的最长无重复字符子串的长度
int Distinct(const char *str)
{
//第一步:判断参数的有效性
if(str == NULL)
{
return 0;
}
//第二步:建立一个哈希表数组用来记录每个字符上次出现过的位置
int n = strlen(str);
int hash[256];
int i;
for(i=0; i<256; i++)
{
hash[i] = -1; //初始化这个哈希表
}
int len = 0; //记录最长无重复字符串的长度
int cur = 0; //记录当前字符无重复字符串的长度
int pre = -1; //记录当前字符的上一个字符向左最远能到达的位置
for(i=0; i<n; i++)
{
/*上一个字符向左最远能到达的位置和当前向左最远能到达的位置比较*/
/*取比较靠右的那个位置*/
pre = (pre > hash[str[i]]? pre : hash[str[i]]);
/*当前字符最长无重复字符串就等于当前位置减去向左最远能到达的位置*/
cur = i - pre;
/*当前字符的最长无重复字符串和之前的最长无重复字符串对比,取较长的那个*/
len = (len > cur? len : cur);
/*记录当前字符的位置*/
hash[str[i]] = i;
}
return len;
}