文章目录
- 1.罗马数字转整数
- 2.最长公共前缀
- 3. 有效的括号
- 4. 找出字符串中第一个匹配项的下标
- 5. 最后一个单词的长度
- 6.二进制求和
- 7.验证回文字符串
- 8. Excel表列名称
- 9. Excel表列序号
- 10. 同构字符串
- 11.有效的字母异位词
- 12.单词规律
- 13. 反转字符串
- 14. 反转字符串的中元音字母
- 15.救赎金
- 16.字符串中的第一个唯一字符
- 17.找不同
- 18. 判断子序列
- 19.最长回文子字符串
- 20.Fizz Buzz
- 21.字符串相加
- 22.字符串中的单词数
- 23.密钥格式化
- 24.键盘行
- 25.检测大写字母
- 26.最长特殊序列
- 27.反转字符串||
- 28.学生出勤记录
- 29.反转字符串中的单词|||
- 30.两个列表的最小索引总和
1.罗马数字转整数
- 将字符所对应的ASCII码作为数组的索引,构造一个一个哈希表出来。
- 然后比字符串中比较,如果当前的比下一个小,那么就减去当前的值
- 否则就加上当前的值
int romanToInt(char* s)
{
char* p = s;
int sum = 0;
int hash[26] = {0};
hash['I' - 'A'] = 1;
hash['V' - 'A'] = 5;
hash['X' - 'A'] = 10;
hash['L' - 'A'] = 50;
hash['C' - 'A'] = 100;
hash['D' - 'A'] = 500;
hash['M' - 'A'] = 1000;
while(*p != '\0')
{
int val = hash[*p - 'A'];
if( p[1] != '\0' && val < hash[p[1] - 'A'])
{
sum -= val;
}
else
{
sum += val;
}
p++;
}
return sum;
}
2.最长公共前缀
该题主要的考察就是在于如何同时比较所有字符串中的各个元素
- 外层的循环是循环字符串长度,而字符串长度取决于全部字符串中长度最小的,因为公共前缀,最大最多只能是里面长度最短的了。
- 内层循环是循环有多少个字符串如果每个字符串都正常结束,那么循环变量一定是等于字符串个数的。否则就是有不一样的。
char* longestCommonPrefix(char** strs, int strsSize)
{
int minlen = 10000;
int i,j;
for (i = 0; i < strsSize; i++)
{
int len = strlen(strs[i]);
if(len < minlen)
{
minlen = len;
}
}
for (j = 0; j < minlen; j++)
{
//j 为不变的 挨个遍历第 j 个元素
for (i = 1; i < strsSize; i++)
{
//发现有一个不一样就结束
if(strs[i-1][j] != strs[i][j])
{
break;
}
}
//如果 i != 总共字符串的个数,证明没有遍历完,中间肯定有不一样的,所有导致提前结束了。
if(i != strsSize)
{
break;
}
}
//就在当前不匹配的地方赋值上 '\0'
strs[0][j] = '\0';
return strs[0];
}
3. 有效的括号
运用栈可以很好的解决整个题
bool isValid(char * s)
{
int len = strlen(s);
char* stack = (char*)malloc(sizeof(char) * (len+1));
char gettop = 0; //栈顶元素
int top = 0; //栈指针
while(*s != '\0')
{
//如果是左括号,那么就入栈
if( *s == '(' || *s == '{' || *s == '[')
{
stack[++top] = *s;
s++;
}
else
{
//如果栈为空,就证明刚的开始第一个就是右括号,如果是这样,就肯顶不能匹配上了
if(top == 0)
{
return false;
}
else
{
//({()})
//栈不为空,开始判断一下三种条件即可,有一个不匹配,直接返回false即可
gettop = stack[top--];
if((gettop == '(' && *s != ')') || gettop == '{' && *s != '}' || gettop == '[' && *s != ']')
{
return false;
}
else
{
//如果全部匹配,那么去找下一个
s++;
}
}
}
}
//栈如果为空,肯定就是全部匹配完成的情况,如果还有元素,那么就是未匹配好的。
return top == 0 ? true : false;
}
4. 找出字符串中第一个匹配项的下标
这是一个匹配字符串的问题
方法一:暴力双for即可解决
- 去挨个遍历源字符串中的字符,如果发现个子字符串的第一个相同
- 然后两个字符串挨个比较即可
int strStr(char* haystack, char* needle)
{
int i,j;
i = j = 0;
int len1 = strlen(haystack);
int len2 = strlen(needle);
//如果要找的比源来的小,直接返回即可
if(len2 > len1)
{
return -1;
}
for (i = 0; i < len1; i++)
{
if(haystack[i] == needle[0])
{
for (j = 1; j < len2; j++)
{
if(haystack[i+j] != needle[j])
{
break;
}
}
if(j == len2)
{
return i;
}
}
}
return -1;
}
5. 最后一个单词的长度
- 既然是找最后一个单词,那么直接求出字符串的长度,
- 然后从后往前找即可
int lengthOfLastWord(char* s)
{
int len = strlen(s);
int i;
int ans = 0;
for (i = len -1; i >= 0; i--)
{
//如果找到了空格,并且在此之前还找到了字母就意味着这个单词结束了
if(s[i] == ' ' && ans != 0)
{
break;
}
//如果不等于空格长度增加
if(s[i] != ' ')
{
ans++;
}
}
return ans;
}
6.二进制求和
- 利用二进制的加法即可,
- 我们创建一个数组,然后将所给的2个数组,从后往前依次加即可,
- 加的时候要注意一个进位的问题
//需要进位
if(carry == 2)
{
ans[index++] = '0';
carry /= 2;
}
else if(carry > 2)
{
ans[index++] = '1';
carry /= 2;
}
else if(carry == 0)
{
ans[index++] = '0';
}
else
{
ans[index++] = '1';
carry = 0;
}
- 最后将字符串逆序回去即可
void Reverse(char* s)
{
int i = 0,j = strlen(s) - 1;
while (i < j)
{
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
i++;
j--;
}
}
char* addBinary(char* a, char* b)
{
int lena = strlen(a);
int lenb = strlen(b);
int i,j,carry;
i = lena - 1; // a 的下标
j = lenb - 1; // b 的下标
carry = 0; // 进位
int maxlen = lena > lenb ? lena : lenb;
char* ans = (char*)malloc(sizeof(char) * (maxlen + 2)); //需要进位和以及后面补'\0'
int index = 0;
while(i >= 0 || j >= 0 || carry != 0)
{
// a 里面还有字符
if(i >= 0)
{
carry += a[i--] - '0'; //a[i] - '0' 就是当前的字符转换为10进制 '1' - '0' = 1 '0' - '0' = 0
}
// b 里面还有字符
if(j >= 0)
{
carry += b[j--] - '0';
}
//需要进位
if(carry == 2)
{
ans[index++] = '0';
carry /= 2;
}
else if(carry > 2)
{
ans[index++] = '1';
carry /= 2;
}
else if(carry == 0)
{
ans[index++] = '0';
}
else
{
ans[index++] = '1';
carry = 0;
}
}
ans[index] = '\0';
Reverse(ans);
return ans;
}
7.验证回文字符串
- 首先将字符串中的所有不是字母和数字的字符去除掉
- 接着双指针判断字符串是否回文即可
//清除字符串中的符号 并且将所有大写转化为小写
char* AdjustStr(char* s)
{
char* newstr = (char*)malloc(sizeof(char) * (strlen(s) + 1));
int index = 0;
while(*s != '\0')
{
//是26个字母
if((*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z') || (*s) >= '0' && (*s) <= '9')
{
//转换为小写全部
newstr[index++] = tolower(*s);
}
s++;
}
newstr[index] = '\0';
return newstr;
}
bool isPalindrome(char* s)
{
s = AdjustStr(s);
int i = 0, j = strlen(s) - 1;
while(i < j)
{
if(s[i] != s[j])
{
return false;
}
i++;
j--;
}
return true;
}
8. Excel表列名称
void Reverse(char* s,int len)
{
int i = 0,j = len -1;
while(i < j)
{
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
i++;
j--;
}
}
char* convertToTitle(int columnNumber)
{
char* ans = (char*)malloc(sizeof(char) * 10);
int index = 0;
while(columnNumber > 0)
{
columnNumber--;
ans[index++] = columnNumber % 26 + 'A';
columnNumber /= 26;
}
ans[index] = '\0';
Reverse(ans,strlen(ans));
return ans;
}
9. Excel表列序号
- 和上题一样,进制转换而已,把他想象成一个26进制即可
int titleToNumber(char* columnTitle)
{
int n = strlen(columnTitle); //位数
int sum = 0;
while(*columnTitle != '\0')
{
//65 是 'A' 64 是@ 也可写成64
sum += ((*columnTitle) - '@') * pow(26,n-1);
columnTitle++;
n--;
}
return sum;
}
10. 同构字符串
- 首先构造两个哈希表出来,将第一个字符串中的每一个字符所对应第二个字符串中的字符
- 如果出现过,判断第一次映射的和第二次出现的需要映射的是否相等即可。
- 最后将第二个字符串重复前面两步即可。
bool isIsomorphic(char* s, char* t)
{
int len = strlen(s);
char* maps[256] = {0};
char* mapt[256] = {0};
int i = 0;
//用s映射t
for (i = 0 ; i < len; i++)
{
if(maps[s[i]] == 0)
{
maps[s[i]] = t[i];
}
if(maps[s[i]] != t[i])
{
return false;
}
}
//用t隐射s
for (i = 0; i < len; i++)
{
if(mapt[t[i]] == 0)
{
mapt[t[i]] = s[i];
}
if(mapt[t[i]] != s[i])
{
return false;
}
}
return true;
}
11.有效的字母异位词
这道题的意思就是:两个字符串中,每个单词出现的次数是否和另一个字符串中出现的次数相同。
- 构造两个哈希表,分别记录s和t两个字符串中单词出现的数量
- 然后对哈希表进行遍历,看看是否对应相等
bool isAnagram(char* s, char* t)
{
int maps[27] = {0};
int mapt[27] = {0};
int i,lens = strlen(s),lent = strlen(t);
if(lens != lent)
{
return false;
}
for (i = 0; i < lens; i++)
{
maps[s[i] - 'a' + 1]++;
mapt[t[i] - 'a' + 1]++;
}
for (i = 0; i < 26; i++)
{
if(maps[i] != mapt[i])
{
return false;
}
}
return true;
}
12.单词规律
这道题和前面的同构字符串是一种类型的题,同样是构造两个哈希表,对其分别进行映射。
- 第一个哈希表好弄,keys可以直接用ASSIC码值充当,一个数组即可
- 第二个哈希表就难弄了,因为它的关键字是字符串,所以我这边是另外构造了一个结构出来的。
下面是我的解法,代码有点长,空间房费也有点大。但是时间快
#define MAX_SIZE 1000
typedef struct
{
char* keys;
char val;
}Map;
typedef struct
{
Map Box[MAX_SIZE];
int size;
}Hash;
//将一句话转化成各个字符串 并且用len 返回新的长度
char** ChangeStr(char* s, int* len)
{
char** newstr = (char**)malloc(sizeof(char*) * (*len));
int i, index = 0, size = 0;;
for (i = 0; i < *len; i++)
{
newstr[size] = (char*)malloc(sizeof(char) * MAX_SIZE);
while (s[i] != ' ' && s[i] != '\0')
{
newstr[size][index++] = s[i++];
}
newstr[size++][index] = '\0';
index = 0;
}
*len = size;
return newstr;
}
//在哈希表中关键字是否有该字符串 如果有返回 下标 否则返回 -1
int FindHash(Hash m, char* cur)
{
int i;
for (i = 0; i < m.size; i++)
{
if (strcmp(m.Box[i].keys, cur) == 0)
{
return i;
}
}
return -1;
}
//初始化
void InitHash(Hash* m, int size)
{
m->size = size;
int i;
for (i = 0; i < m->size; i++)
{
m->Box[i].keys = (char*)malloc(sizeof(char) * MAX_SIZE);
}
}
bool wordPattern(char* pattern, char* s)
{
int lenp = strlen(pattern);
int lens = strlen(s);
char** tmp = ChangeStr(s, &lens);
//长度不同直接返回false
if (lenp != lens)
{
return false;
}
char** mapstr = (char**)calloc(26, sizeof(char*));
int i;
//字母作为关键字,字符串作为值
for (i = 0; i < lenp; i++)
{
//如果p中的当前字母没有映射所对应的单词,那么映射单词
if (mapstr[pattern[i] - 'a'] == 0)
{
mapstr[pattern[i] - 'a'] = (char*)malloc(sizeof(char) * MAX_SIZE);
strcpy(mapstr[pattern[i] - 'a'], tmp[i]);
}
//如果p中当前字母所映射的单词,和新单词不同,那么证明错误
if (strcmp(tmp[i], mapstr[pattern[i] - 'a']) != 0)
{
return false;
}
}
//字符串作为关键字,值为字母
Hash mapalp;
InitHash(&mapalp,lens);
for (i = 0; i < lenp; i++)
{
int index = FindHash(mapalp, tmp[i]);
//去哈希表中找该字符串是否由对应的单词
if (index == -1) //如果没有,那么插入
{
strcpy(mapalp.Box[i].keys, tmp[i]);
mapalp.Box[i].val = pattern[i];
}
else
{
if (mapalp.Box[index].val != pattern[i])
{
return false;
}
}
}
return true;
}
13. 反转字符串
- 额。。。。
- 双指针,前后走
void reverseString(char* s, int sSize){
int i = 0, j = sSize - 1;
while (i < j)
{
int temp = s[i];
s[i++] = s[j];
s[j--] = temp;
}
}
14. 反转字符串的中元音字母
- 找到原因字母,
- 然后交换位置
int vowel(char c)
{
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')
{
return 1;
}
else
{
return 0;
}
}
char * reverseVowels(char * s){
int i = 0, j = strlen(s) - 1;
while(i < j){
while(i < j && !vowel(s[i]))
{
i++;
}
while(i < j && !vowel(s[j]))
{
j--;
}
char t = s[i];
s[i] = s[j];
s[j] = t;
i++;
j--;
}
return s;
}
15.救赎金
该题的题意就是让你在magazine字符串中的所有字母,是否可以构造ransownote的字符串
- 构造一个哈希表,统计一下第二个字符串中各个字母共有多少个
- 然后在第一个字符串中去遍历,减去,如果小于0就说明多出来了。
bool canConstruct(char* ransomNote, char* magazine)
{
//创建一个哈希表,记录magazine 里面有多少字母可以用
int map[26] = {0};
int i,lenr = strlen(ransomNote), lenm = strlen(magazine);
if(lenr > lenm)
{
return false;
}
for (i = 0; i < lenm; i++)
{
map[magazine[i] - 'a']++;
}
for (i = 0; i < 26; i++)
{
printf("%d ",map[i]);
}
for (i = 0; i < lenr; i++)
{
map[ransomNote[i] - 'a']--;
if(map[ransomNote[i] - 'a'] < 0)
{
return false;
}
}
return true;
}
16.字符串中的第一个唯一字符
- 构造一个哈希表出来,记录每个字符出现的次数
- 然后在此遍历该字符串,去哈希表中去查看,自己出现了几次,如果出现了1次,那么就是它了
- 切记不可以直接遍历哈希表,看谁出现1次,因为那样子,保证不了题目中所说的顺序
int firstUniqChar(char* s)
{
int map[26] = {0};
int len = strlen(s);
int i;
for (i = 0; i < len; i++)
{
map[s[i] - 'a']++;
}
//在遍历依次字符串
for (i = 0; i < len; i++)
{
if (map[s[i] - 'a'] == 1)
{
return i;
}
}
//error
//如果遍历哈希表的话会出现先后的问题
// for (i = 0; i < 26; i++)
// {
// if(map[i] == 1)
// {
// return i;
// }
// }
return -1;
}
17.找不同
该题的意思就是看一个字符串比另一个字符串多出了哪一个字符
- 构造两个哈希表出来
- 分别遍历两个字符串,是哈希表完整
- 接着比较哈希表是否相同,不同的位置,就是多出来的那个字符。
char findTheDifference(char* s, char* t)
{
int maps[26] = {0};
int mapt[26] = {0};
int i,lens = strlen(s),lent = strlen(t);
//构造两个字符串的哈希表
for (i = 0; i < lent; i++)
{
if(i < lens)
{
maps[s[i] - 'a']++;
}
mapt[t[i] - 'a']++;
}
for (i = 0; i < 26; i++)
{
if(maps[i] != mapt[i])
{
return i + 'a';
break;
}
}
return ' ';
}
18. 判断子序列
s是否是t的子序列,切记注意是有顺序的,题目中最后也举出了例子
双指针
- 用两个指针,分别指向两个字符串
- 如果相等,那么就同时向后走,
- 如果不相等,那么只有t中的向后走。
- 当其中有一个走完的时候,就可以结束了
- 如果 s 中的走完 证明一定找到了此字符串
- 否则就是没找到
bool isSubsequence(char* s, char* t)
{
int i = 0,j = 0;
int lens = strlen(s);
int lent = strlen(t);
while(i < lens && j < lent )
{
if(s[i] == t[j])
{
i++;
j++;
}
else
{
j++;
}
}
if(i == lens)
{
return true;
}
else
{
return false;
}
}
19.最长回文子字符串
- 首先构造一个哈希表出来
- 统计每个字母出现的次数
- 如果是偶数次,则该字母一定可以构成回文
- 如果是奇数次,那么该字母的 n - 1 就一定是偶数了
- 还要要注意的就是单独出现一次的那一个字母得加进去
int longestPalindrome(char * s)
{
int map[52] = {0};
int i,len = strlen(s);
int ans = 0;
int flag = 0; // 代表出现一次的字母
//记录每个字母出现的次数
for (i = 0; i < len; i++)
{
if(s[i] >= 'a' && s[i] <= 'z')
{
map[s[i] - 'a']++;
}
else
{
map[s[i] - 'A' + 26]++;
}
}
for (i = 0; i < 52; i++)
{
//如果出现偶数次,那么一定都能构成回文
if( map[i] > 0 && map[i] % 2 == 0 )
{
ans += map[i];
}
//如果出现奇数次,把他前 n - 1 次一定是偶数
if(map[i] > 0 && map[i] % 2 != 0)
{
ans += map[i]-1;
flag = 1;
}
}
if(flag == 1)
{
ans += 1;
}
return ans;
}
20.Fizz Buzz
判断是否是3 5 15 的倍数即可
char ** fizzBuzz(int n, int* returnSize){
char ** answer = (char **)malloc((sizeof(char *) * (n)));
char * arr = (char *)malloc(sizeof(char) * n *9);
*returnSize = n;
for(int i=0;i<n;i++)
{
answer[i] = &arr[9*i];
}
for(int i = 1; i <= n; i++)
{
if(i % 3 == 0 && i % 5 == 0)
{
strcpy(answer[i-1],"FizzBuzz");
}
else if(i % 3 == 0)
{
strcpy(answer[i-1],"Fizz");
}
else if(i % 5 == 0)
{
strcpy(answer[i-1],"Buzz");
}
else
{
sprintf(answer[i-1],"%d",i);
}
}
return answer;
}
这道题题有问题!!!!!题目中说索引从1开始,完了我就从1开始,结果一直错,内存问题,折磨我半小时,看评论才知道题目有问题!
21.字符串相加
这道题和该目录中过的第6题也是leetcode里的67题二进制求和是一样的,这个是10进制求和而已
- 唯一就是在判断那个进位变量的时候不同,
- 还要注意在ASCII码中没有十几这样的数字,所以在求模的时候得注意.
- 依旧和前面的二进制求和代码逻辑是一样的,从后往前加,加到ans中最后逆序。
void Reverse(char* s,int len)
{
int i = 0,j = len -1;
while(i < j)
{
char tmp = s[i];
s[i++] = s[j];
s[j--] = tmp;
}
}
char * addStrings(char * num1, char * num2)
{
int i,j,len1 = strlen(num1),len2 = strlen(num2);
i = len1 - 1;
j = len2 - 1;
int maxlen = len1 > len2? len1 : len2;
char* ans = (char*)malloc(sizeof(char) * (maxlen + 2)); //需要进位和补'\0'
int index = 0,tmp = 0;
while(i >= 0 || j >= 0 || tmp != 0)
{
if(i >= 0)
{
tmp += num1[i] - '0';
}
if(j >= 0)
{
tmp += num2[j] - '0';
}
//不需要进位
if(tmp < 10)
{
ans[index++] = tmp + '0';
tmp = 0;
}
else
{
ans[index++] = (tmp%10) + '0';
//ans[index++] = (tmp + '0') % 10; Error
tmp = 1;
}
i--;
j--;
}
ans[index] = '\0';
Reverse(ans,index);
return ans;
}
22.字符串中的单词数
因为每一个句子是由空格分隔开的,所以,只要当前的不是空格,而自己前面的那一个是空格,就证明新的单词开始了。但是一定要注意字符串的第一个字母,运用i-1会出现越界,再加一个条件即可
int countSegments(char * s)
{
int count = 0,i,len = strlen(s);
for (i = 0; i < len; i++)
{
if( (i == 0 || s[i-1] == ' ') && s[i] != ' ')
{
count++;
}
}
return count;
}
23.密钥格式化
思路是从后往前
- 从后面把每一段都设置成k次就好了
- 最后逆序即可
void Reverse(char* s,int len)
{
int i = 0,j = len - 1;
while(i < j)
{
char tmp = s[i];
s[i++] = s[j];
s[j--] = tmp;
}
}
char* licenseKeyFormatting(char* s, int k)
{
int count = 0, i;
int len = strlen(s);
char* ans = (char*)malloc(sizeof(char) * (len*2));
int index = 0;
int num = 0; //记录当前这一段有多少个字母了
char ch;
for (i = len -1; i >= 0;i--)
{
ch = s[i];
if(ch == '-')
{
continue;
}
else
{
//小写转大写
if(ch >= 'a' && ch <= 'z')
{
ch = ch - 'a' + 'A';
}
//一段完成
if(num >= k)
{
ans[index++] = '-';
num = 0;
}
ans[index++] = ch;
num++;
}
}
ans[index] = '\0';
Reverse(ans,index);
return ans;
}
24.键盘行
- 首先构造一个哈希表,记录26个英文字母在哪一行
- 然后去遍历每个单词,去哈希表中查,看看其中字母是否在同一行即可。
一定要注意,开辟空间的时候要注意’\0’所以要多开辟一个空间!!!!!!!
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
//当前的val是那一行的英文字母
int CheckRow(int val)
{
char* s1 = "qwertyuiop";
char* s2 = "asdfghjkl";
char* s3 = "zxcvbnm";
int i;
int len1 = strlen(s1);
int len2 = strlen(s2);
int len3 = strlen(s3);
char ch = val;
for (i = 0; i < len1; i++)
{
if(ch == s1[i])
{
return 1;
}
}
for (i = 0; i < len2; i++)
{
if(ch == s2[i])
{
return 2;
}
}
for (i = 0; i < len3; i++)
{
if(ch == s3[i])
{
return 3;
}
}
return 0;
}
char ** findWords(char ** words, int wordsSize, int* returnSize)
{
int map[26] = {0};
char** ans = (char**)malloc(sizeof(char*) * wordsSize);
*returnSize = 0;
int i;
int row;
//构造哈希表得出26个英文字母在哪一行
for (i = 97; i <= 122; i++)
{
row = CheckRow(i);
map[i - 'a'] = row;
}
for (i = 0; i < wordsSize; i++)
{
int j;
int k = strlen(words[i]);
//去遍历每个字母
for (j = 1; j < k; j++)
{
char prev = tolower(words[i][j - 1]);
char cur = tolower(words[i][j]);
if(map[prev - 'a'] != map[cur - 'a'])
{
break;
}
}
//如果全部比较完 j == k 就证明这一个单词里面的所有字母都在同一行
if(j == k)
{
ans[(*returnSize)] = (char*)malloc(sizeof(char) * (k+1));
strcpy(ans[(*returnSize)],words[i]);
(*returnSize)++;
}
}
return ans;
}
25.检测大写字母
看题目可以知道,后面所有的字母,都必须和第二个字母的大小写相同,只有这样子才是正确的。另外我们还需要判断,如果当首字母是小写,第二个也必须是小写。
bool detectCapitalUse(char* word)
{
int i,len = strlen(word);
if(len == 1)
{
return true;
}
for (i = 2; i < len; i++)
{
//后面的都必须和第二个相等
if(isupper(word[i]) != isupper(word[1]))
{
return false;
}
}
//如果第一个是小写,那么第二个必须也是小写
if(islower(word[0]) && isupper(word[1]))
{
return false;
}
return true;
}
26.最长特殊序列
绷不住了,真绷不住了!!!!!
int findLUSlength(char* a, char* b)
{
int lena = strlen(a),lenb = strlen(b);
if(lena != lenb)
{
return lena > lenb ? lena : lenb;
}
if(strcmp(a,b) == 0)
{
return -1;
}
return lena;
}
好好好好!
27.反转字符串||
char* reverseStr(char* s, int k)
{
int i, len = strlen(s);
for (i = 0; i < len; i += (k*2))
{
k = i + k > len ? len - i : k;
int begin = i;
int end = i + k - 1;
while(begin < end)
{
char tmp = s[begin];
s[begin++] = s[end];
s[end--] = tmp;
}
}
return s;
}
28.学生出勤记录
这道题的意思就是说,如果整个字符串中出现两个A 或者是三个连在一起的L那么就返回false 否则 返回true
- 我们只需要对字符串进行遍历,如果碰到A那么计数,
- 碰到L进行判断他的后几个是否也是。
方法一:暴力枚举
直接对该数组进行一个遍历。
bool checkRecord(char* s)
{
int i,len = strlen(s);
int numA = 0;
int numL = 0;
for (i = 0; i < len; i++)
{
if(s[i] == 'A')
{
numA++;
if(numA == 2)
{
return false;
}
}
if(s[i] == 'L')
{
numL = 0;
int j;
for (j = i; j < len && s[j] == 'L'; j++)
{
numL++;
if(numL == 3)
{
return false;
}
}
}
}
return true;
}
方法二: 这种方法相对于上面的,在判断L的时候改成了两个if语句,时间上快了不。
bool checkRecord(char * s)
{
int numA = 0;
int slen = strlen(s);
for(int i = 0; i < slen; i++)
{
if(s[i] == 'A')
{
numA++;
if(numA >= 2)
{
return false;
}
}
else
{
if(i + 2 < slen)
{
if(s[i] == 'L' && s[i + 1] == 'L' && s[i+2] == 'L')
return false;
}
}
}
return true;
}
29.反转字符串中的单词|||
反转字符串都会,这里就是把大字符串拆分成小的字符串就好了。
方法一: 这是我第一时间想到的,就是求出当前单词的长度,然后反转整个单词。
- 求出当前单词的长度,然后进行反转
- 将i 变成下一个单词的开头。
int MyStrlen(char*s)
{
int count = 0;
while(*s != ' ' && *s != '\0')
{
count++;
s++;
}
return count;
}
char* reverseWords(char* s)
{
int i = 0,len = strlen(s);
while(i < len)
{
int curlen = MyStrlen(&s[i]);
int left = i;
int right = left + curlen - 1;
while (left < right)
{
char tmp = s[left];
s[left++] = s[right];
s[right--] = tmp;
}
i = i + curlen + 1;
}
return s;
}
方法2: 看了别人题解后,其实思路整体也就是这个思路,只是人家的更加的简洁?效率更快?
char* reverseWords(char* s)
{
int i = 0,j,len = strlen(s);
int left,right;
while(i < len)
{
j = i;
while(s[j] != ' ' && j < len)
{
j++;
}
left = i;
right = j - 1;
while(left < right)
{
char tmp = s[left];
s[left++] = s[right];
s[right--] = tmp;
}
i = j + 1;
}
return s;
}
30.两个列表的最小索引总和
没什么技巧,我这里就是暴力求解的。超过5%的人。。。就先这样吧
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
char** findRestaurant(char** list1, int list1Size, char** list2, int list2Size, int* returnSize)
{
int maxsize = list1Size > list2Size ? list1Size : list2Size;
char** ans = (char**)malloc(sizeof(char*) * maxsize);
int i,j,minindexsum = 9999;
*returnSize = 0;
for (i = 0; i < list1Size; i++)
{
for (j = 0; j < list2Size; j++)
{
//相等
if(strcmp(list1[i],list2[j]) == 0)
{
//如果相同则继续录入
if((i + j == minindexsum) || minindexsum == 9999)
{
minindexsum = i + j;
ans[*returnSize] = (char*)malloc(sizeof(char) * (strlen(list1[i]) + 1));
strcpy(ans[(*returnSize)++],list1[i]);
continue;
}
if(i + j < minindexsum)
{
minindexsum = i + j;
strcpy(ans[(*returnSize)-1],list1[i]);
}
}
}
}
return ans;
}