目录
坚持每一天。
—、第一题
1. 原题链接
原题链接:917. 仅仅反转字母
给你一个字符串 s ,根据下述规则反转字符串:
所有非英文字母保留在原有位置。
所有英文字母(小写或大写)位置反转。
返回反转后的 s 。
2. 解题思路
双指针,两个指针指向字符串两端,两端都为字母则交换,左端或右端为别的字符则进行加加或减减。
3. 代码
char * reverseOnlyLetters(char * s){
int len = strlen(s);
int i = 0, j = len-1;
char centrce;
while(i < j){
if(s[i] < 'A' || s[i] > 'z'){
++i;
continue;
}
if(s[i] > 'Z' && s[i] < 'a'){
++i;
continue;
}
if(s[j] < 'A' || s[j] > 'z'){
--j;
continue;
}
if(s[j] > 'Z' && s[j] < 'a'){
--j;
continue;
}
centrce = s[i];
s[i] = s[j];
s[j] = centrce;
++i;
--j;
}
return s;
}
二、第二题
1. 原题链接
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
2. 解题思路
有序数组递增排列,两个指针指向字符串两端,两端之和大于target,大的一端减减,两端之和小于target,小的一端加加,两端之和等于target,返回下标。
3. 代码
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
* returnSize = 2;
int* ans = (int*)malloc(sizeof(int)*2);
int sum;
int i = 0, j = numbersSize-1;
while(i < j){
sum = numbers[i] + numbers[j];
if(sum > target){
--j;
}
else if(sum < target){
++i;
}
else if(sum == target){
ans[0] = i+1;
ans[1] = j+1;
return ans;
}
}
return 0;
}
三、第三题
1. 原题链接
原题链接:165. 比较版本号
给你两个版本号 version1 和 version2 ,请你比较它们。
版本号由一个或多个修订号组成,各修订号由一个 ‘.’ 连接。每个修订号由 多位数字 组成,可能包含 前导零 。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0 ,下一个修订号下标为 1 ,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。
比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较 忽略任何前导零后的整数值 。也就是说,修订号 1 和修订号 001 相等 。如果版本号没有指定某个下标处的修订号,则该修订号视为 0 。例如,版本 1.0 小于版本 1.1 ,因为它们下标为 0 的修订号相同,而下标为 1 的修订号分别为 0 和 1 ,0 < 1 。
返回规则如下:
如果 version1 > version2 返回 1,
如果 version1 < version2 返回 -1,
除此之外返回 0。
2. 解题思路
以版本号的 .
为节点,把两个版本号的字符转成数字进行比较。
3. 代码
int compareVersion(char * version1, char * version2){
int i = 0, j = 0;
int sum1 = 0, sum2 = 0;
while(version1[i] != '\0' || version2[j] != '\0'){
sum1 = 0;
while(version1[i] != '.' && version1[i] != '\0'){
sum1 = sum1*10 + (version1[i]-'0');
++i;
}
sum2 = 0;
while(version2[j] != '.' && version2[j] != '\0'){
sum2 = sum2*10 + (version2[j]-'0');
++j;
}
if(sum1 > sum2) return 1;
if(sum1 < sum2) return -1;
if(version1[i] != '\0') ++i;
if(version2[j] != '\0') ++j;
}
return 0;
}
四、第四题
1. 原题链接
原题链接:443. 压缩字符串
给你一个字符数组 chars ,请使用下述算法压缩:
从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 :
如果这一组长度为 1 ,则将字符追加到 s 中。
否则,需要向 s 追加字符,后跟这一组的长度。
压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 10 或 10 以上,则在 chars 数组中会被拆分为多个字符。
请在 修改完输入数组后 ,返回该数组的新长度。
你必须设计并实现一个只使用常量额外空间的算法来解决此问题。
2. 解题思路
双指针,一个指针在原地并存储字符,等待另一个指针字符和原地指针不等时,则进行字符赋值和计算字符个数,并通过把数字格式化成字符进行赋值。直至循环完毕。
3. 代码
int compress(char* chars, int charsSize){
int flag = 0;
int i, j, p;
char ans[5];
for(i = 0, j = 0; i<charsSize; j=i){
while(i < charsSize && chars[i] == chars[j])
++i;
chars[flag++] = chars[j];
if(i-j==1)
continue;
sprintf(ans,"%d",i-j);
for(p = 0; p<strlen(ans); ++p)
chars[flag++] = ans[p];
}
return flag;
}
五、星球推荐
星球链接:英雄算法联盟
星球里有什么?
【朋友圈】一个极致精准的自律、编程、算法的小圈子。
【算法集训】以月为单位组织算法集训,每天四题,风雨无阻。
【排行榜】每天、每周都会有榜单,激励大家不断进步,不断成长。
【个人规划】每个人都写好自己的规划,也可以查看他人的规划,时刻警醒自己不掉队。
【打卡挑战】每日一题打卡、每日早起打卡、算法集训打卡、规划完成情况打卡。
在星球里做什么?
目前星球人数达到290+,在星球里你能够遇到一群志同道合之人,因为都是花钱进来的,你不会看到任何浑水摸鱼的人,每个人都有自己的每月规划,星主每月都会组织算法集训,每天一起刷题,你可以看到别人的解题报告,取其之长,补己之短。