[解题报告]《算法零基础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;
}


相关文章
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
184 1
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
C语言算法复杂度
【10月更文挑战第20天】
65 5
C语言算法复杂度
C语言在实现高效算法方面的特点与优势,包括高效性、灵活性、可移植性和底层访问能力
本文探讨了C语言在实现高效算法方面的特点与优势,包括高效性、灵活性、可移植性和底层访问能力。文章还分析了数据结构的选择与优化、算法设计的优化策略、内存管理和代码优化技巧,并通过实际案例展示了C语言在排序和图遍历算法中的高效实现。
133 2
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
119 1
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
131 1
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
246 7
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
222 8

热门文章

最新文章