1. 排序数组
- 题目
给你一个整数数组
nums
,请你将该数组升序排列。
- 题目分析
- 直接使用c语言的内置函数
qsort
就可以完成该题
- 源码实现
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int *cmp(int *a, int *b)
{
return *a - *b;
}
int* sortArray(int* nums, int numsSize, int* returnSize){
qsort(nums, numsSize, sizeof(int), cmp);
*returnSize = numsSize;
return nums;
}
2. 多数元素
- 题目
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
- 题目分析
根据题目的定义可以推导出,只需要找到
n/2
的位置中的元素,由于给定的数组元素是无序的,所以在找之前需要对其排序,排序完成后直接返回n/2
位置的元素
- 源码实现
int cmp(int *a, int *b)
{
return *a - *b;
}
int majorityElement(int* nums, int numsSize){
qsort(nums, numsSize, sizeof(int), cmp);
return nums[numsSize / 2];
}
3.存在重复元素
- 题目
给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回
true
。如果数组中每个元素都不相同,则返回false
。
- 题目分析
重复元素意味着至少存在两个元素,对其进行排序后,我们就只需要比较当前元素与相邻元素即可
- 源码实现
int cmp(const void* a, const void* b) {
return *(int *)a - *(int *)b;
}
//先排序后比较
bool containsDuplicate(int* nums, int numsSize) {
qsort(nums, numsSize, sizeof(int), cmp);
for (int i = 0; i < numsSize - 1; i++) {
if (nums[i] == nums[i + 1]) {
return true;
}
}
return false;
}
4. 最大间距
- 题目
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
- 思路分析
要想找最大的间距,就需要找到较大的数与较小的相邻数,在无序的数组中这是比较难操作的,对其进行排序后就能简化操作,这样就只需要相邻元素两两相减,更新最大间距即可
- 源码实现
int cmp(const void* a, const void* b)
{
return *(int *)a - *(int *)b;
}
int maximumGap(int* nums, int numsSize){
if(numsSize < 2) //数组元素个数小于2直接返回0
{
return 0;
}
qsort(nums, numsSize, sizeof(int), cmp);
int i;
int max_num = 0;
int num;
for(i = 0; i < numsSize - 1; ++i)
{
num = nums[i + 1] - nums[i]; //比较相邻元素的差值
max_num = num > max_num ? num:max_num; //保存最大间距
}
return max_num;
}
5. 按奇偶排序数组
- 题目
给定一个非负整数数组
A
,返回一个数组,在该数组中,A
的所有偶数元素之后跟着所有奇数元素。你可以返回满足此条件的任何数组作为答案。
- 题目分析
这道题有多种思路,这里我使用的内置函数
qsort
实现按奇偶排序。数组元素为奇数时将元素向右移,为偶数时数组元素向左移。利用
&
运算,为奇数时回调函数返回值大于0,向右移动,反之向左移动。
- 源码实现
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int Qua(int a)
{
return (a & 1); //奇数时为1,偶数时为0
}
int cmp(const void *a, const void* b)
{
return Qua(*(int *)a) - Qua(*(int *)b); //为奇数时,大于0,往右排
}
int* sortArrayByParity(int* nums, int numsSize, int* returnSize){
int *ans = (int *)malloc(sizeof(int) * numsSize);
//改变数组中元素或元素位置,一般没特殊要求建议创建新数组。
int i;
for(i = 0; i < numsSize; ++i)
{
ans[i] = nums[i];
}
qsort(ans, numsSize, sizeof(int), cmp);
*returnSize = numsSize;
return ans;
}
6. 最小时间差
- 题目
给定一个 24 小时制(小时:分钟 “HH:MM”)的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。
- 题目分析
思路:先将字符串转成对应的整数,排序之后比较数组元素中的差值,保存最小的时间差,最后的结果要注意时间循环(类比12进制的时钟)。
- 题目给出的是字符串数组,找最小时间差就需要先将字符串转成对应的整数,使用
sscanf
函数实现- 转成整数后全部换算成分钟进行比较
- 将分钟进行排序,然后找两者之间最小差值
- 最后注意时间循环,如果不注意,就会出现
23:59 00:00
之间的差值为1439,实际上结果是1。
- 源码实现
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int findMinDifference(char ** timePoints, int timePointsSize){
//1.首先将字符串转成整数
//2.将整数转换成分钟
//3.将分钟进行排序处理
//4.找出相邻间隔之间的最小值
//5.注意时间的循环
int *ans = (int *)malloc(sizeof(int) * timePointsSize);
int i;
int a, b;
for(i = 0; i < timePointsSize; ++i)
{
sscanf(timePoints[i], "%d:%d", &a, &b);
ans[i] = a * 60 + b;
}
qsort(ans, timePointsSize, sizeof(int), cmp);
int min = 1440; //要保证最小的时间差,就初始化为时间的最大值
for(i = 1; i < timePointsSize; ++i)
{
min = fmin(min, ans[i] - ans[i - 1]);
}
min = fmin(min , ans[0] - ans[timePointsSize - 1] + 1440); //24小时为一循环
return min;
}
7. 三角形的最大周长
- 题目
给定由一些正数(代表长度)组成的数组
A
,返回由其中三个长度组成的、面积不为零的三角形的最大周长。如果不能形成任何面积不为零的三角形,返回
0
。
- 题目分析
利用贪心算法思想,要想得到最大的周长的值,只需要判断该数组中最大的三个元素是否构成三角形。
- 构成三角形的条件:任意两边之和大于第三边。三个元素任意两个组合相加判断是否大于第三边固然是可以的,但是操作复杂且时间复杂度高,不建议使用。
- 像这种情况我们可以先进行排序,排序之后我们发现
a < b < c
已经得出两个结论b + c > a
和a + c < b
,现在只需要比较a + b > c
- 最后求最大周长的值
- 源码实现
int cmp(const void* a, const void *b)
{
return *(int *)a - *(int *)b;
}
int largestPerimeter(int* nums, int numsSize){
if(numsSize < 2) //两个元素是无法构成三角形的
{
return 0;
}
qsort(nums, numsSize, sizeof(int), cmp);
int i;
//从最后的元素开始遍历,只要能构成三角形,那么结果就为最大周长
for(i = numsSize - 1; i >= 2; --i)
{
if(nums[i - 2] + nums[i - 1] > nums[i])
{
return nums[i - 2] + nums[i - 1] + nums[i];
}
}
return 0;
}
8. 救生艇
- 题目
第 i 个人的体重为
people[i]
,每艘船可以承载的最大重量为limit
。每艘船最多可同时载两人,但条件是这些人的重量之和最多为
limit
。返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/boats-to-save-people
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
- 题目分析
要求所需最小船数,就必须保证每次乘坐的是能乘坐的最大值。这种情况使用排序就比较方便对其进行求解。
- 第一步,排序
- 第二步,判断最大的体重和最小体重能否一起乘坐一艘船,能就一起走,不能就先让体重大的人先走
- 第三步,返回结果
- 源码实现
int cmp(const void* a, const void *b)
{
return *(int *)a - *(int *)b;
}
int numRescueBoats(int* people, int peopleSize, int limit){
//体重people[i] , 船能承载的最大体重是limit
//同时载两人
//求载到每一个人所需的最小船数
qsort(people, peopleSize, sizeof(int), cmp);
int ans = 0; //统计船的数量
int left = 0;
int right = peopleSize - 1;
while(left <= right)
{
if(left == right) //只有一个人了,直接走
{
++ans;
break;
}
else if(people[left] + people[right] > limit) //最小的与最大的比较,如果大于就让最大的先走
{
++ans;
right--;
}
else
{
++ans;
right--;
left++;
}
}
return ans;
}
总结
以上的所有的题目均参考博主英雄哪里出来的文章,此次最大的收获就是对排序算法的使用,并了解了C语言内置函数qsort
函数的使用方法。