目录
一:知识点
1,排序介绍
2,qsort
二,习题
1,912. 排序数组 - 力扣(LeetCode) (leetcode-cn.com)
2,169. 多数元素 - 力扣(LeetCode) (leetcode-cn.com)
3,217. 存在重复元素 - 力扣(LeetCode) (leetcode-cn.com)
4,164. 最大间距 - 力扣(LeetCode) (leetcode-cn.com)
5,905. 按奇偶排序数组 - 力扣(LeetCode) (leetcode-cn.com)
6,539. 最小时间差 - 力扣(LeetCode) (leetcode-cn.com)
7,976. 三角形的最大周长 - 力扣(LeetCode) (leetcode-cn.com)
8,881. 救生艇 - 力扣(LeetCode) (leetcode-cn.com)
三,总结
一:知识点
1,排序介绍
排序,就是将一组数按要求有序排列。
2,qsort
今天主要介绍的是qosrt。qsort是c语言中自带的一个排序函数。可以实现各种类型数据的排序。qsort的主要参数是要排序的数组,数组的大小,排序数据的类型大小,以及一个比较函数。这个比较的函数是需要自己来写的,从而来实现排序各种类型的数据。
主体大概如下:
int arr[10];
qsort(arr,sizeof(arr),sizeof(int),cmp);
而对于cmp而言
int cmp(const void*e1,const void*e2)
?需要返回一个整数来表示如何排序
返回数值 | 排序方法 | >0 | e1排在e2后 | =0 | e1和e2排序不定 | <0 | e1排在e2前 |
?而这里使用void*指针主要是为了接受各种类型的数据,在cmp函数内部我们需要自己再进行强制类型转换从而得到该地址下的数据
int cmp(const void*e1,const void*e2)
{
return *(int*)e1-*(int*)e2;
}
至于比较的方法,如果数据相减不会超出数据类型范围可以直接如上写 。
int cmp(const void*e1,const void*e2)
{
if(*(int*)e1>*(int*)e2)
return 1;
else
return 0;
}
可以使用比较来表示排的序,避免数据的溢出。?
二,习题
大家可以先去做题再来看。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp_int(const void*e1,const void*e2)
{
if(*(int*)e1>=*(int*)e2)
return 1;
else
return 0;
}
int* sortArray(int* nums, int numsSize, int* returnSize)
{
qsort(nums,numsSize,sizeof(int),cmp_int);
*returnSize=numsSize;
return nums;
}
直接用qsort就可以了
int cmp(const void*e1,const void*e2)
{
if(*(int*)e1>=*(int*)e2)
return 1;
else
return 0;
}
int majorityElement(int* nums, int numsSize)
{
if(numsSize==1)
return nums[0];
qsort(nums,numsSize,sizeof(int),cmp);
printf("%d",nums[0]);
int i=0;
int max=1;
for(i=1;i<numsSize;i++)
{
if(nums[i]!=nums[i-1])
max=1;
if(nums[i]==nums[i-1])
max++;
if(max>numsSize/2)
{
return nums[i];
}
}
return 0;
}
先排序,排序完之后遍历数组寻找。只要nums【i】与前一个数不相等,就是一个新的数,让max重新变成1再统计个数,直到找到个数大于n/2的数
int cmp(const void*e1,const void*e2)
{
if(*(int*)e1>=*(int*)e2)
return 1;
else
return 0;
}
bool containsDuplicate(int* nums, int numsSize)
{
if(numsSize==1)
return false;
qsort(nums,numsSize,sizeof(int),cmp);
int i=0;
for(i=0;i<numsSize-1;i++)
{
if(nums[i]==nums[i+1])
return true;
}
return false;
}
排序完之后,遍历数组,只要有某两个前后的数相同即为true。
int cmp(const void*e1,const void*e2)
{
if(*(int*)e1>=*(int*)e2)
return 1;
else
return 0;
}
int maximumGap(int* nums, int numsSize)
{
if(numsSize<2)
return 0;
qsort(nums,numsSize,sizeof(int),cmp);
int max=nums[1]-nums[0];
int i=0;
for(i=1;i<numsSize-1;i++)
{
if(nums[i+1]-nums[i]>max)
max=nums[i+1]-nums[i];
}
return max;
}
先处理特殊情况n<2。之后对数组直接排序,然后遍历数组相减存在max中,遍历完就可以得到最大的间距了。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* sortArrayByParity(int* nums, int numsSize, int* returnSize)
{
int* ret=(int*)malloc(sizeof(int)*numsSize);
int k=0;
int j=numsSize-1;
int i=0;
for(i=0;i<numsSize;i++)
{
if(nums[i]%2==0)
{
ret[k]=nums[i];
k++;
}
else
{
ret[j]=nums[i];
j--;
}
}
*returnSize=numsSize;
return ret;
}
因为只要奇数在偶数之后即可,那我们就遍历数组看每个元素是什么,判断其奇偶,偶数从0开始往后放,奇数从最后一个位置开始往前放。
int findMinDifference(char ** timePoints, int timePointsSize)
{
int i=0;
int min=abs((((timePoints[0][0]-'0')*10)+(timePoints[0][1]-'0'))*60+(timePoints[0][3]-'0')*10+(timePoints[0][4]-'0')-(((timePoints[1][0]-'0')*10)+(timePoints[1][1]-'0'))*60-(timePoints[1][3]-'0')*10-(timePoints[1][4]-'0'));
printf("%d",min);
for(i=0;i<timePointsSize;i++)
{
int j=0;
for(j=0;j<timePointsSize;j++)
{
if(j==i)
continue;
int dic;
if(abs(((timePoints[i][0]-'0')*10+timePoints[i][1]-'0')-((timePoints[j][0]-'0')*10+timePoints[j][1]-'0'))>12)
{
dic=abs((((timePoints[i][0]-'0'+2)*10)+(timePoints[i][1]-'0'+4))*60+(timePoints[i][3]-'0')*10+(timePoints[i][4]-'0')-(((timePoints[j][0]-'0')*10)+(timePoints[j][1]-'0'))*60-(timePoints[j][3]-'0')*10-(timePoints[j][4]-'0'));
}
else
dic=abs((((timePoints[i][0]-'0')*10)+(timePoints[i][1]-'0'))*60+(timePoints[i][3]-'0')*10+(timePoints[i][4]-'0')-(((timePoints[j][0]-'0')*10)+(timePoints[j][1]-'0'))*60-(timePoints[j][3]-'0')*10-(timePoints[j][4]-'0'));
// else
// dic=abs((((timePoints[i][0]-'0')*10)+(timePoints[i][1]-'0'))*60+(timePoints[i][3]-'0')*10+(timePoints[i][4]-'0')-(((timePoints[j][0]-'0')*10)+(timePoints[j][1]-'0'))*60-(timePoints[j][3]-'0')*10-(timePoints[j][4]-'0'));
if(min>dic)
{
min=dic;
}
}
}
return min;
}
这个就不说什么了,代码比较乱。思路就是全转成分钟再比较。
int cmp(const void*e1,const void*e2)
{
if(*(int*)e1<=*(int*)e2)
return 1;
else
return 0;
}
int largestPerimeter(int* nums, int numsSize)
{
qsort(nums,numsSize,sizeof(int),cmp);
int i;
for(i=0;i<numsSize-2;i++)
{
if(nums[i+2]+nums[i+1]>nums[i])
return nums[i]+nums[i+1]+nums[i+2];
}
return 0;
}
主要是贪心的思想。先由大到小排序,让最大数(当前,也就是nums【i】)前两个数相加,如果大于它,那么这三个数相加就是最大的三角形周长。而如果小于或者等于,其他数都比这两个数来得小,加起来肯定也不能大于nums【i】也就是这个数不能作为三角形一边。
int cmp(const void*e1,const void*e2)
{
if(*(int*)e1<=*(int*)e2)
return 1;
else
return 0;
}
int numRescueBoats(int* people, int peopleSize, int limit)
{
qsort(people,peopleSize,sizeof(int),cmp);
printf("%d",people[0]);
int count=0;
int left=0;
int right=peopleSize-1;
for(;left<right;)
{
if(people[left]+people[right]<=limit)
{
count++;
left++;
right--;
}
else
{
count++;
left++;
}
}
if(left==right)
count++;
return count;
}
也是贪心的思想,和上一题差不多。先由大到小排序,如果最重的一个人(当前)不能和最轻的一个人(当前)一起走,那么最重的那个人谁也不能一起走,只能自己乘一船。然后最重的人就变成了第二重的人,再进行比较。如此循环直到载完。
三,总结
万人千题,每天写题,争取早日达到千题目标。
|