算法思想:
思路一:
1.首先判断第一个元素是否为大写字母,初始化ishave为false表示不含有大写字母,若有将其置为true
2.若第一个字母为大写字母
下一个字母为大写字母,那么接下来每个字母只能为大写字母
下一个字母为小写字母,那么接下来每个字母只能为小写字母
若第一个字母不为大写字母 接下来每个字符只能为空或小写字母
思路二:
思路二:
1.直接设置计数器up统计大写字母的个数
若未出现大写字母 遍历完成后则直接返回true
若大写字母个数小于等于下标时,则说明中间存在小写字母 直接返回false
2.结尾判断是否大写字母的个数等于字符串长度或小于等于1,若是返回true 否则返回false(说明存在末尾存在小写字符)
思路一(自己的想法)
bool detectCapitalUse(char * str){
int i = 0;
bool ishave = (str[i] >= 'A' && str[i] <='Z') ? true:false;
if(ishave == false) //若不含有大写字母
{
for(int i = 1;str[i] != '\0';i++)
if(str[i] >= 'A' && str[i] <='Z')
return false;
}
else
{
if(str[i+1] >= 'A' && str[i+1] <='Z') //若第二个字符仍为大写
for(int i = 1;str[i] != '\0';i++) //从第二个遍历到最后 若出现非大写则返回false
{
if(!(str[i] >= 'A' && str[i] <='Z'))
return false;
}
else //若第二个字符为小写
for(int i = 1;str[i] != '\0';i++) //从第二个遍历到最后 若出现大写返回false
{
if(str[i] >= 'A' && str[i] <='Z')
return false;
}
}
return true;
}
思路二
bool detectCapitalUse(char * str){
int up = 0;
for(int i = 0; str[i] != '\0';i++)
{
if(str[i] >= 'A' && str[i] <='Z')
{
up++;
if(up <= i)
return false;
}
}
if(up == strlen(str) || up <= 1)
return true;
else
return false;
}
算法思想:
1.设置双指针i,j分别指向字符串头和字符串尾
2.当表头与表尾指针i,j未相遇时,指针i向右遍历,直到遇到第一个字母或数字字符,指针j向左遍历,直至遇到第一个字母或数字字符
3.判断遍历到元素是否相等,若相等则指针继续相向前进
char Tolower (char a) //将字符转为小写,若本身已经是小写或是数字则直接返回
{
if(a >= 'A' && a <= 'Z')
return a+32;
return a;
}
bool isNumOrChar (char a) //判断是否为字符或者数字
{
if(a >= '0' && a <= '9')
return true;
else if(a >= 'a' && a <= 'z')
return true;
else if(a >= 'A' && a <= 'Z')
return true;
return false;
}
bool isPalindrome(char * s){
int len = strlen(s);
if(len <= 1)
return true;
int i = 0, j = len - 1;
while(i < j)
{
while(i < j && !(isNumOrChar(s[i]))) i++; //指针i向右遍历,直到遇到第一个字母或数字字符
while(i < j && !(isNumOrChar(s[j]))) j--; //指针j向左遍历,直至遇到第一个字母或数字字符
if(i < j && Tolower(s[i]) != Tolower(s[j]))
return false;
i++;
j--;
}
return true;
}
算法思想:
方法一:横向比较
1.初始化最长公共前缀为第一列,公共前缀的长度大小为num
2.从第二个字符串到最后一个字符串开始比较 将每个字符串的元素与第一个字符串进行比较 直到找到第一个不同的元素,此时下标更新为更小的
3.将第一个字符串中下标为num的字符置为’\0’,返回第一个字符串
方法二:纵向比较
1.比较每一列元素是否与第一列元素相同
2.直到找到第一个字符串元素不同的列,将其边界设为下标i,直接返回第一个字符串
本题采用方法二
char * longestCommonPrefix(char ** strs, int strsSize){
if(strsSize == 0)
return "";
if(strsSize == 1)
return strs[0];
for(int i = 0; i < strlen(strs[0]); i++) //遍历每列
{
for(int j = 1; j < strsSize; j++) //遍历每个字符串
if(strs[j][i] != strs[0][i])
{
strs[0][i] = '\0'; //直接退出循环并设置边界为i
return strs[0];
}
}
return strs[0];
}
算法思想:
1.遍历字符串,若前一个元素是空格当前元素不是空格,则单词个数加一
2.需要对第一个元素做特殊判断,若第一个元素不是空格,则单词个数加一
int countSegments(char * str){
int i = 0, count = 0;
while(str[i] != '\0')
{
if((i == 0 || str[i-1] == ' ') && str[i] != ' ')
count++;
i++;
}
return count;
}
算法思想:
1.初始化计数器count统计字符个数,从结尾开始遍历,遇到非空格元素时个数加一
2.若count == 0且当前元素为空格则继续前进(需要滤掉后面的空格)
若count != 0时且当前元素为空格则直接返回count
3.遍历结束返回count 则说明字符串长度就是字符个数
int lengthOfLastWord(char * str){
int len = strlen(str), count = 0;
for(int i = len - 1; i >= 0; i--)
{
if(str[i] != ' ') //若遇到非空格元素 则更新count的个数
count++;
else if(str[i] == ' ' && count == 0) //滤掉后面的空格
continue;
else
return count;
}
return count;
}
算法思想:经典双指针思想,交换即可
void reverseString(char* str, int sSize){
if(sSize <= 1)
return;
for(int i = 0; i < sSize / 2; i++)
{
char temp = str[i];
str[i] = str[sSize - 1 - i];
str[sSize - 1 - i] = temp;
}
}
方法二实际上是方法一的更加好写的版本
void reverseString(char* str, int sSize){
int left = 0, right = sSize - 1;
while(left < right)
{
char temp = str[left];
str[left] = str[right];
str[right] = temp;
left++;
right--;
}
}
算法思想:
1.先求出字符串的长度,然后从第一个字符开始,每隔2k个字符进行遍历
2.双指针法反转长度为k的字符串,left设置为当前下标i,判断i+k-1是否越界,若越界,right置为字符串长度,若未越界则right=i+k-1
3.每隔2k个长度的字符串,将前k个交换
char * reverseStr(char * str, int k){
int len = strlen(str);
int left, right;
for(int i = 0; i < len; i += 2 * k)
{
left = i;
if(i + k - 1 <= len - 1) // 从位置i到i+k-1共计k个元素 若未越界 则令右指针为该下标
right = i + k - 1;
else
right = len - 1; //若已经越界 则令右指针为最后一个下标
while(left < right)
{
char temp = str[left];
str[left] = str[right];
str[right] = temp;
left++;
right--;
}
}
return str;
}
算法思想:结合字符串与单词的思想
1.遍历字符串,当遇到字符时,前一个不是字符或为第一个元素时,将left置为当前下标,
同时向后遍历,直到遇到空格或字符串结尾,
设置right为遍历结束前一个元素,若未遍历到结尾,则将下标加一
2.对遍历到的单词进行双指针法反转
char * reverseWords(char * str){
int i = 0, left, right;
while(str[i] != '\0')
{
if((i == 0 || str[i - 1] == ' ') && str[i] != ' ')
{
left = i; //将左指针指向单词的第一个字母
while(str[i] != ' ' && str[i] != '\0')//找到第一个空格
i++;
right = i -1;
if(str[i] != '\0')
i++;
while(left < right) //反转字符串
{
char temp = str[left];
str[left] = str[right];
str[right] = temp;
left++; right--;
}
}
}
return str;
}
算法思想:
1.双指针思想的快慢指针思想,设置快指针i指向字符串尾部,从字符串尾部开始向前遍历寻找第一个非空格字符
2.当找到第一个非空格字符后,将慢指针j设置为该字符下标,然后让快指针i继续向前走,寻找第一个空格字符
3.将快指针i+1到慢指针j的元素复制到结果字符串中
4.结尾还需要对新创建的字符串增加’\0’结尾标志(去除最后一个无效的空格)
char * reverseWords(char * str){
int len = strlen(str);
int i = len - 1, j, count = 0;
char *result = (char*)malloc(sizeof(char) * (len+1));
while(i >= 0)
{
while(i >= 0 && str[i] == ' ' ) i--; //从后向前寻找第一个非空格
if(i >= 0) //若未遍历到第一个元素 则将j置为i
j = i; //慢指针j设置为该字符下标
else //若遍历完就已经结束
break;
while(i >= 0 && str[i] != ' ') i--; //寻找第一个空格
for(int k = i + 1; k <= j; k++)
result[count++] = str[k];
result[count++] = ' '; //count
}
if(count == 0)
result[0] = '\0'; //若无字母 直接第一个元素即为空
else
result[count-1] = '\0'; //去除最后一个无效的空格
return result;
}
算法思想:1.利用哈希表B,C统计未出现在对应位置的元素,bulls统计正确元素个数
2.遍历字符串,若secret[i]==guess[i],则将bull加一,否则让B[i]++,C[i]++
3.扫描哈希表,统计重叠元素个数,即为cow的个数
int min (int a, int b)
{
if(a > b)
return b;
return a;
}
char * getHint(char * secret, char * guess){
int bull = 0, cow = 0;
int B[10] = {
0}, C[10] = {
0};
for(int i = 0; secret[i] != '\0'; i++)
{
if(secret[i] == guess[i]) //secret[i]==guess[i],则将bull加一,否则让B[i]++,C[i]++
bull++;
else
{
B[secret[i] - '0']++;
C[guess[i] - '0']++;
}
}
for(int i = 0; i < 10; i++)
{
cow += min(B[i],C[i]);
}
char *str = (char*)malloc(sizeof(char) * 10);
sprintf(str, "%dA%dB", bull, cow);
return str;
}
算法思想:1.遍历字符串 统计出连续的数字个数 保存在数组count中
2.遍历count 连续子字符串的数量为 sum += min(count[i], count[i+1])
int min(int a, int b)
{
if(a < b)
return a;
return b;
}
int countBinarySubstrings(char * s){
int len = strlen(s);
if(len <= 1)
return 0;
int* count = (int*)malloc(sizeof(int) * 50001);
int pre = s[0], num = 0, k = 0;
int sum = 0;
for(int i = 0; i < len; i++)
{
if(pre == s[i]) //若与之前相同
num++;
else //若不同则更新
{
count[k++] = num;
num = 1;
pre = s[i];
}
}
count[k] = num;
for(int i = 0; i < k; i++)
sum += min(count[i], count[i+1]);
return sum;
}
算法思想:
1.比较两个字符串的大小,取较长的字符串长度+2为返回字符串的长度,因为可能需要进位1,且还需要将最后一位设置为\0
2.从最后一个元素开始向前遍历,直至两个字符串均遍历到结尾结束,将字符串a的数字与字符串数字b上的数字相加,若其中一个字符串遍历到0则将该 位置加0,将结果取余为该位数字,add为二者的进位
3.若需要进位,则直接将第一位设置为1,若无需进位,则将所有元素向前移动一个单位
char * addBinary(char * a, char * b){
int lena = strlen(a), lenb = strlen(b);
int maxlen = lena > lenb ? lena+2 : lenb+2;
char* result = (char*)malloc(sizeof(char) * (maxlen));
result[maxlen - 1] = '\0';
int add = 0; //用于表示进位
for(int i = lena - 1, j = lenb - 1, k = maxlen - 2; i >= 0 || j >= 0; i--, j--, k--)
{
int sum = add;
if(i >= 0)
sum += a[i] - '0';
if(j >= 0)
sum += b[j] - '0';
result[k] = sum % 2 + '0'; //更新result数组的值
add = sum / 2;
}
if(add == 1)
result[0] = '1'; //若需要进位,则直接将第一位设置为1
else //若无需进位,则将所有元素向前移动一个单位
{
for(int i = 0; i < maxlen - 1; i++)
result[i] = result[i + 1];
result[maxlen - 1] = '\0';
}
return result;
}
同类型题415. 字符串相加
43. 字符串相乘
算法思想:1.初始化长为lena+lenb+1的int型数组result用于保存结果,让一个字符串的每一位与另一个字符串的另一位相乘,执行结果为 result[i+j] += (nums1[i]-‘0’) * (nums2[j] - ‘0’)
2.对result数组进行进位,用add保存向下一位的进位数
3.若进位结束后,add不为零,则需要将每个数字向后移动一位
4.将result的结果赋值给返回字符串res
char * multiply(char * num1, char * num2){
int lena = strlen(num1), lenb = strlen(num2);
if(num1[0] == '0' || num2[0] == '0') //若第一项为0,直接返回0
{
num1[0] = '0';
num1[1] = '\0';
return num1;
}
int maxlen = lena + lenb + 1;
int* result = (int*)malloc(sizeof(int) * maxlen);
char* res = (char*)malloc(sizeof(char) * maxlen);
for(int i = 0; i <= maxlen-1; i++) //两位数相乘 不进位情况下最高的一位为lena+lenb-2
{
result[i] = 0;
}
for(int i = lena - 1; i >= 0; i--)
for(int j = lenb - 1; j >= 0; j--)
{
result[i + j] += (num1[i] - '0') * (num2[j] - '0');
}
int add = 0;
for(int i = lena + lenb - 2; i >= 0; i--)
{
result[i] += add;
add = result[i] / 10;
result[i] = result[i] % 10;
}
if(add == 0)//判断最后一项是否需要进位
{
res[maxlen - 2] = '\0';
for(int i = 0; i < maxlen - 2; i++)
res[i] = result[i] + '0';
}
else
{
for(int i = maxlen - 2; i > 0; i--)
{
result[i] = result[i - 1];
}
res[maxlen - 1] = '\0';
for(int i = 1; i <= maxlen - 2; i++)
res[i] = result[i] + '0';
res[0] = add + '0';
}
return res;
}
算法思想:朴素模式匹配算法
1.从目标串字符开始出发,与比对字符串逐个字符比较
2.每次执行设置j=0,表示每次比对字符串走的步数,当j等于比对串的长度时,说明匹配成功,否则目标串向后移动一个单位
int strStr(char * haystack, char * needle){
int lena = strlen(haystack), lenb = strlen(needle);
if(lena == 0 && lenb != 0)
return -1;
else if(lenb == 0)
return 0;
int i = 0;
while(i <= lena - lenb) //若长度不足,则不再遍历
{
int j = 0;
while(haystack[i] == needle[j] && j < lenb) //从目标串字符开始出发,与比对字符串逐个字符比较
{
i++;
j++;
}
if(j == lenb)
return i - j;
i = i - j + 1;
}
return -1;
}