前言
☀️排序是c语言的基本算法之一,学好排序,是学习算法的良好开端。
324.摆动序列II
⚡️ 题目描述
给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]… 的顺序。
你可以假设所有输入数组都可以得到满足题目要求的结果。
题目分析
根据题目要求,摆动数列形成的条件是一小一大,而且为了避免大的数字没有小的数字大,可以把大的数分成一类,小的数再分成一类。这样就用到了排序。于是解题过程可以描述为:
排序->二分->按顺序插入->得出结果
int imp(const void* p1,const void* p2){
return (*(int*)p2)-(*(int*)p1);
}
void wiggleSort(int* nums, int numsSize){
qsort(nums,numsSize,sizeof(int),imp);
int *ret=(int*)malloc(sizeof(int)*numsSize);//排序
for(int i=0;i<numsSize;i++){
if(i%2==0){
ret[i]=nums[numsSize/2+i/2];//按顺序插入
}else{
ret[i]=nums[(i-1)/2];
}
}
for(int i=0;i<numsSize;i++){
nums[i]=ret[i];//输出
}
}
总结
题目本身的描述看上去比较难,但实际上一联系到排序可能难度就回直线下降。解这题的关键个人认为是能够理解摆动数列的产生原理(直接),然后用电脑实现的时候就会发现难点(排序可以解决)
350.两个数组的交集II
⚡️ 题目描述
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
题目分析
题目的要求是求交集,而如果是仅仅求交集的话,那么一个循环就可以解决,而现在要求统计个数(虽然两个循环也能解决)但是排序后一个循环便能解决。
int imp(const void *p1,const void *p2){
return *(int*)p1-*(int *)p2;
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
qsort(nums1,nums1Size,sizeof(int),imp);
qsort(nums2,nums2Size,sizeof(int),imp);
int p=0;
int n=nums1Size>nums2Size?nums1Size:nums2Size;
int *ret=(int *)malloc(sizeof(int)*n);
for(int i=0,j=0;i<nums1Size&&j<nums2Size;i++,j++){
if(nums1[i]==nums2[j]){
ret[p++]=nums1[i];
}else if(nums1[i]>=nums2[j]){
i--;
}else{
j--;
}
}
*returnSize=p;
return ret;
}
总结
排序可以优化解题方法(也有可能负优化)
164.最大间距
⚡️ 题目描述
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
题目分析
本题的普通解法(排序+遍历)可以很轻松的解决(听说还有高级解法)。先排序,之后循环遍历更新两个数之间的最大值。
int imp(const void *p1,const void *p2){
return (*(int*)p1)-(*(int*)p2);
}
int maximumGap(int* nums, int numsSize){
if(numsSize<2)return 0;
qsort(nums,numsSize,sizeof(int),imp);
int i=0,max=0;
while(i<=numsSize-2){
if(nums[i+1]-nums[i]>max)max=nums[i+1]-nums[i];
i++;
}
return max;
}
总结
英雄哥曾经说过:“其实很多东西都能转变成数学模型。”
题目本身可能很难,但是转化为数学模型就会很简单,而对于排序而言,追求用排序简化问题才是他的本质。