[解题报告]《算法零基础100讲》(第41讲) C语言 排序 API

简介: [解题报告]《算法零基础100讲》(第41讲) C语言 排序 API

全文目录

  ☘前言☘

 🎁主要知识点

            1.排序 API

            2.比较函数

 📓课后习题

            912. 排序数组

            169. 多数元素

            217. 存在重复元素

            164. 最大间距

            905. 按奇偶排序数组

            137. 只出现一次的数字 II

            剑指 Offer II 075. 数组相对排序

            539. 最小时间差

            976. 三角形的最大周长

            881. 救生艇

            面试题 10.02. 变位词组

 📑写在最后

☘前言☘

今天是算法零基础打卡的第41天,题目本身不难,主要是为了理解基数排序的。上链接:

《算法零基础100讲》(第41讲) C语言 排序 API

全文大约阅读时间: 20min


🧑🏻作者简介:一个从工业设计改行学嵌入式的年轻人

✨联系方式:2201891280(QQ)


🎁主要知识点

1.排序 API

排序API的作用就是传入一个数组,按照规定规则进行就地排序。


void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));


参数 说明

base 指向要排序的数组的第一个元素的指针

nitems 由base指向的数组中元素的个数

size     数组中每个元素的大小,以字节位单位。

compar 用来比较两个元素的函数,即函数指针(比较算法的回调函数)

2.比较函数

这里我给一个极度简洁的递增写法。


int cmp1(char *a,char *b){
    return *a > *b ? 1 : -1;
}


可以知道当 a>b时 返回值就是1,否则就是返回-1.


📓课后习题

912. 排序数组

912. 排序数组


给你一个整数数组 nums,请你将该数组升序排列。

解题思路


直接排序返回就好了呗?

int cmp(const void *a,const void *b){
    return *(int *)a - *(int *)b;
}
int* sortArray(int* nums, int numsSize, int* returnSize){
    qsort(nums,numsSize,sizeof(int),cmp);
    *returnSize = numsSize;
    return nums;
}


169. 多数元素

169. 多数元素


给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。


解题思路


写了好几遍了。。。。因为是大于,所以用一个最多元素和其它元素相消除最终剩下的一定是最多的元素。由这个思想可以写出来下面的代码。


int majorityElement(int* nums, int numsSize){
    int maxnum = 0,maxtime = 0;
    for(int i = 0;i < numsSize;i++){
        if(maxtime == 0){  //未选定最大元素
            maxnum = nums[i];
            maxtime++;
        }
        else if(nums[i] == maxnum) maxtime++;
        else maxtime--;
    }
    return maxnum;
}


217. 存在重复元素

217. 存在重复元素


给定一个整数数组,判断是否存在重复元素。

如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。


解题思路


直接排序,然后顺序查看就好了。如果有重复的就返回true


int cmp(int *a,int *b){
    return *a > *b;
}
bool containsDuplicate(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),cmp);
    for(int i = 1;i < numsSize;i++)
        if(nums[i] == nums[i-1])    return true;
    return false;
}


164. 最大间距

164. 最大间距


给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。

如果数组元素个数小于 2,则返回 0。


解题思路


直接排序,然后顺序算间距就完事了。


int cmp(int *a, int *b){return *b < *a;}
int maximumGap(int* nums, int numsSize){
    qsort(nums ,numsSize ,sizeof(int) ,cmp);
    int max = 0;
    for(int i = 1;i < numsSize;i++)
        //printf("%d",nums[i] - nums[i - 1]);
        if(max < nums[i] - nums[i - 1]) max = nums[i] - nums[i - 1];
    return max;
}


905. 按奇偶排序数组

905. 按奇偶排序数组


给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。

你可以返回满足此条件的任何数组作为答案。


解题思路


按照要求写规则,排就好了。


int cmp(int *a, int *b){
    if((*a)&1)      //a是奇数
        if((*b)&1) return *a > *b;//b也是奇数
        else return 1;  //偶数在前
    else 
        if((*b)&1) return -1;
        else return *a > *b;
}
int* sortArrayByParity(int* nums, int numsSize, int* returnSize){
    *returnSize = numsSize;
    qsort(nums,numsSize,sizeof(int),cmp);
    return nums;
}


137. 只出现一次的数字 II

137. 只出现一次的数字 II


给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。


解题思路


用位运算更好玩0.0 因为每个数字都出现了三次,那么每位的数字和一定是3的倍数,余数就是只有一个数字的对应位。


int singleNumber(int* nums, int numsSize){
    unsigned ans = 0;
    for(unsigned i = 0;i < 32;i++){
        unsigned  temp = 0;
        for(int j = 0;j < numsSize;j++)
            temp += (((unsigned) 1<<i)&nums[j])>>i;        //计算此位所有元素的和
        temp %= 3;  //求唯一元素这一位是啥
        ans += temp << i;
    }
    return ans;     //强制类型转换
}


剑指 Offer II 075. 数组相对排序

剑指 Offer II 075. 数组相对排序


给定两个数组,arr1 和 arr2,


arr2 中的元素各不相同

arr2 中的每个元素都出现在 arr1 中

对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。


解题思路


按照要求排就好了。我用了hash表直接映射位置,省的找了。


int hash[1001];
int cmp(int *a,int *b){
    if(hash[*a] && hash[*b])    return hash[*a] > hash[*b];//都在2中出现
    else if(hash[*a] || hash[*b]) return hash[*a] < hash[*b];//只有一个出现
    return *a > *b;  //都没出现
}
int* relativeSortArray(int* arr1, int arr1Size, int* arr2, int arr2Size, int* returnSize){
    memset(hash,0,sizeof(hash));
    for(int i = 0;i <arr2Size;i++)
        hash[arr2[i]] = i + 1;//初始化hash表为位置+1,为了和没有做区分
    *returnSize = arr1Size;
    qsort(arr1,arr1Size,sizeof(int),cmp);
    return arr1;
}


539. 最小时间差

539. 最小时间差


给定一个 24 小时制(小时:分钟 “HH:MM”)的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。


解题思路


直接转化为分钟表示,排序,然后计算最小的时候,初始化为最小和最大的间距就好了。


int cmp(int *a,int*b){
    return *a > *b;
}
int findMinDifference(char ** timePoints, int timePointsSize){
    int hash[timePointsSize],hashSize = 0;
    for(int i = 0;i<timePointsSize;i++)     //
        hash[hashSize++] = (((timePoints[i][0] -'0') * 10) + timePoints[i][1] - '0') * 60 + (timePoints[i][3] - '0')*10 + timePoints[i][4]; //转化为分钟
    qsort(hash,hashSize,sizeof(int),cmp);
    int min = 24*60+hash[0] - hash[hashSize - 1];
    for(int i = 1;i < hashSize;i++)
        if(min>hash[i]-hash[i-1])   min = hash[i] - hash[i-1];
    return min;
}


976. 三角形的最大周长

976. 三角形的最大周长


给定由一些正数(代表长度)组成的数组 A,返回由其中三个长度组成的、面积不为零的三角形的最大周长。

如果不能形成任何面积不为零的三角形,返回 0。


解题思路


直接排序,如果最大值减中间值>最小值就可以构成三角形。


int cmp(int *a,int *b){return *a > *b;}
int largestPerimeter(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),cmp);
    int i;
    for(i = numsSize - 1;i > 1;i--){
        if(nums[i] < nums[i-1] + nums[i - 2])   break;
    }
    if(i == 1) return 0;
    else return nums[i] + nums[i - 1] + nums[i-2];
}


881. 救生艇

881. 救生艇


第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。

每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。

返回载到每一个人所需的最小船数。(保证每个人都能被船载)。


解题思路


贪心思想,最大值如果不能和最小值同船就只能自己一条船。


int cmp(int *a,int *b){return *a > *b;}
int numRescueBoats(int* people, int peopleSize, int limit){
    qsort(people,peopleSize,sizeof(int),cmp);
    int low = 0, high = peopleSize - 1,ans = 0;
    while(low <= high){
        if(people[low] + people[high] > limit)  --high;
        else ++low,--high;
        ans++;
    }
    return ans;
}


面试题 10.02. 变位词组

面试题 10.02. 变位词组


编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。


解题思路


创建一个数据结构,将原始串和排序完的串做映射,因为变位词排序完之后肯定是都相同的。所以可以用strcmp来做判断再做一次排序,然后分表就好了。


typedef struct vs{
    char *str;
    char *vstemp;
}vs;
int cmp1(char *a,char *b){
    return *a > *b;
}
int cmp2(vs *a,vs *b){
    return strcmp(a->vstemp,b->vstemp);
}
char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes){
    vs temp[strsSize];
    for(int i = 0;i < strsSize;i++){
        temp[i].str = strs[i];
        int len = strlen(temp[i].str);
        temp[i].vstemp = malloc(sizeof(char)*(len+1));
        temp[i].vstemp[0] = 0;
        strcat(temp[i].vstemp,temp[i].str);
        qsort(temp[i].vstemp,len,sizeof(char),cmp1);  //比较字符串的排序
    }
    qsort(temp,strsSize,sizeof(vs),cmp2);             //整体排序
    int colsize[9900],col,size = 1;
    colsize[0] = 1;
    for(int i = 1;i <strsSize;i++){
        if(strcmp(temp[i].vstemp,temp[i-1].vstemp))    size++,colsize[size - 1] = 1;
        else   colsize[size-1] ++;
    }
    *returnSize = size;
    (*returnColumnSizes) = malloc(sizeof(int)*size);
    char ***ans = malloc(sizeof(char **) * size);
    for(int i = 0;i <size;i++) (*returnColumnSizes)[i] = colsize[i],ans[i] = malloc(sizeof(char *) * colsize[i]);
    size = 0,col = 0;
    //写入数据
    for(int i = 0;i < strsSize;i++){
        if(!colsize[size]) size++,col = 0;
        int len = strlen(temp[i].str);
        ans[size][col] = malloc(sizeof(char)*(len +1));
        ans[size][col][0] = '\0';
        strcat(ans[size][col],temp[i].str);
        colsize[size]--;
        col++;
    }
    return ans;
}


相关文章
|
9天前
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
33 4
|
10天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
51 8
|
10天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
41 7
|
1月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
51 9
|
1月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
23 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
1月前
|
算法 Java 程序员
【算法每日一练及解题思路】有n级台阶,一次只能上1级或2级,共有多少种走法?
本文深入解析了“爬楼梯问题”,探讨了递归与迭代两种解法,并提供了Java代码实现。通过分析问题本质,帮助读者理解动态规划技巧,提高解决实际编程问题的能力。关键词:Java, 算法, 动态规划, 爬楼梯问题, 递归, 迭代。
66 0
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
31 0
|
1月前
|
API 数据安全/隐私保护 开发者
淘宝 API:关键词搜商品列表接口,助力商家按价格销量排序分析数据
此接口用于通过关键词搜索淘宝商品列表。首先需在淘宝开放平台注册并创建应用获取API权限,之后利用应用密钥和访问令牌调用接口。请求参数包括关键词、页码、每页数量、排序方式及价格区间等。返回结果含总商品数量及具体商品详情。使用时需注意签名验证及官方文档更新。
|
1月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
72 0
|
1月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)