目录
题目一:2078. 两栋颜色不同且距离最远的房子
街上有 n 栋房子整齐地排成一列,每栋房子都粉刷上了漂亮的颜色。给你一个下标从 0 开始且长度为 n 的整数数组 colors ,其中 colors[i] 表示第 i 栋房子的颜色。
返回 两栋 颜色 不同 房子之间的 最大 距离。
第 i 栋房子和第 j 栋房子之间的距离是 abs(i - j) ,其中 abs(x) 是 x 的绝对值。
解题思路:
直接遍历每栋房子,若此栋房子之后的房子颜色不同,则计算它们之间的距离,将距离最大的用变量max进行存储。
代码:
int maxDistance(int* colors, int colorsSize){
int i = 0;
int k;
int S;
int max = 0;
while(i < colorsSize) //遍历每栋房子
{
k = i+1;
while(k < colorsSize) //遍历此栋房子之后的所有房子
{
if(colors[k] != colors[i]) //颜色不同则计算距离并且与当前记录的max比较
{
S = abs(k - i);
if(S > max)
max = S;
}
k++;
}
i++;
}
return max;
}
题目二:561. 数组拆分 I
给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
解题思路:
如果我们采用试数的方式, 若第一对中含有1这个数字,因为1是最小的数,那么与1成对的另一个数则一定会被舍弃。其实这里就有点田忌赛马的感觉,用1和其他数中最小的数字(即2)绑定,接着,用3和其他数中最小的数字(即4)绑定,这样,到所有数成对时,min的总和值就会最大。
所以数就分成min[1,2], min[3,4], min[5,6]..........[2n-1,2n]
因此,结果就是排序后,每个数组下标为奇数的值相加。
代码:
int Findpos(int *a, int low, int high) //快排
{
int val = a[low];
while(low < high)
{
while(low < high && a[high] >= val)
high--;
a[low] = a[high];
while(low < high && a[low] <= val)
low++;
a[high] = a[low];
}
a[low] = val;
return high;
}
void Quicksort(int *a,int low, int high)
{
if(low < high)
{
int pos = Findpos(a,low,high);
Quicksort(a,low,pos-1);
Quicksort(a,pos+1, high);
}
}
int arrayPairSum(int* nums, int numsSize){
int sum = 0;
if(numsSize== 0)
return;
Quicksort(nums,0,numsSize-1);
for(int i=0;i<numsSize; i+=2) //下标为奇数的值相加
{
sum = sum + nums[i];
}
return sum;
}
刚开始排序的时候使用的是冒泡,结果超出时间限制,然后就采用时间复杂度更小的快速排序来排,不过说实话C语言略微有点麻烦,许多功能都得自己实现,不像python,C++等可以直接调用库函数。
题目三:1323. 6 和 9 组成的最大数字
给你一个仅由数字 6 和 9 组成的正整数
num
。你最多只能翻转一位数字,将 6 变成 9,或者把 9 变成 6 。
请返回你可以得到的最大数字。
解题思路:
看示例其实就是遍历数字的最高位到最低位,如果是6,则把它变成9,然后输出。
int maximum69Number (int num){
int shuliang = 0;
int a[5];
while(num != 0) //从个位到最高位进行提取,放到a数组中
{
a[shuliang] = num%10;
num = num /10;
shuliang++;
}
int i,res = 0;
for(i=shuliang-1; i>=0; i--) //最高位到最低位,如果是6,则把它变成9,接着break退出循环
{
if(a[i] == 6)
{
a[i] = 9;
break;
}
}
for(i=shuliang-1; i>=0; i--) //将数组内的数字组合成结果
{
res = res * 10 + a[i];
}
return res;
}
题目四:942. 增减字符串匹配
由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表示为长度为 n 的字符串 s ,其中:
如果 perm[i] < perm[i + 1] ,那么 s[i] == 'I'
如果 perm[i] > perm[i + 1] ,那么 s[i] == 'D'
给定一个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中 任何一个 。
解题思路:
刚开始看题目还有点云里雾里,看了一下题解才知道大概的意思,求解的话就是定义两个双指针i与j,其中i = 0,j= strlen(s),进一步的,i其实是代表从[0,strlen(s)]这个范围中能选到的最小值,如i=0,即当前在上述的范围中能选到的最小值为0;
而J是代表从[0,strlen(s)]这个范围中能选到的最大值,如j=strlen(s),即当前在上述的范围中能选到的最大值为strlen(s)。
如果当前位置字符串的值为‘I’,则代表后一元素一定比当前位置大,那么当前位置的值一定是在未选择数中最小的(即为i的值),那么后者无论如何都会比当前位置的值要大;同样的,若为'D',则在未选择数中选最大的(即为j的值)。
而在代码层面:遍历字符串s,如果s[k] =='I'则将i的值赋给新数组exam[k],并且i加一;反之则将j的值赋给exam[k],并且j加1。
代码:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* diStringMatch(char * s, int* returnSize){
int i = 0; //定义i和j的值
int len = strlen(s);
int j = len;
int * exam = (int *)malloc(sizeof(int) * (len+1)); //动态分配数组
for(int k=0; k<len; k++) //遍历字符串数组s中的所有元素
{
if(s[k] == 'I')
{
exam[k] = i;
i++;
}
else if(s[k] == 'D')
{
exam[k] = 'D';
j--;
}
}
exam[len] = i; //最后i一定会等于j,把i或j放到数组最后一个元素中
return exam;
}