《九日集训》第六日 C排序函数,及有序数组的应用

一、今日知识点总结

  1. 使用qsort()函数进行对数组的排序

    void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));
    qsort(base,nitems.sizeof(int),compar);
    
  2. qsort()函数中的比较函数

    //对整形数据的比较函数
    int compar(const void *p1,const void *p2){
        return (*(int *)p1)-(*(int *)p1);
    }
    
    • compar返回值小于0,p1在左p2在右(升序)
    • compar返回值等于0,顺序不变
    • compar返回值大于0,p1在右p2在左(降序)
  3. ** 指向指针的指针(二级指针)

    char **cc;
    int ** in;
    
  4. void * :void * 为**“无类型指针”**

    在上面比较函数中,需要先将指针类型,强制类型转化为(int *)这个类型的指针。

  5. N级指针

    想要获取指针指向的数据时,一级指针加一个*,二级指针加两个*,三级指针加三个*,以此类推,请看代码:

    #include <stdio.h>
    int main(){
        int a =100;
        int *p1 = &a;
        int **p2 = &p1;
        int ***p3 = &p2;
        printf("%d, %d, %d, %d\n", a, *p1, **p2, ***p3);
        printf("&p2 = %#X, p3 = %#X\n", &p2, p3);
        printf("&p1 = %#X, p2 = %#X, *p3 = %#X\n", &p1, p2, *p3);
        printf(" &a = %#X, p1 = %#X, *p2 = %#X, **p3 = %#X\n", &a, p1, *p2, **p3);
        return 0;
    }
    
    运行结果
    100, 100, 100, 100
    &p2 = 0X28FF3C, p3 = 0X28FF3C
    &p1 = 0X28FF40, p2 = 0X28FF40, *p3 = 0X28FF40
    &a = 0X28FF44, p1 = 0X28FF44, *p2 = 0X28FF44, **p3 = 0X28FF44
    
  6. %#X 解释

    其中的%#表示的输出提示方式
    1. 如果是8进制,在前面加0
    2.如果是十进制,不加任何字符
    3.如果是十六进制,会加上0x

    //举例说明:当a=41;
    printf(“a=%#o\n”,c);//输出的是:0101(把16进制41转化为8进制)   ++加了0补足
    printf(“a=%#d\n”,c);//输出的是:65(把16进制41转化为10进制)	不变
    printf(“a=%#x\n”,c);//输出的是:0x41							++加了0x
    
  7. LeetCode 关于 Note: The returned array must be malloced, assume caller calls free().

    这句话的含义是你实现完对应的功能的时候,你需要使用malloc创建数组的空间,然后返回这个用mallco创建的数组

  8. sscanf() – 从字符串读取格式化输入。解析字符串的好方法

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
      int day, year;
      char weekday[20], month[20], dtm[100];
    
      strcpy( dtm, "Saturday March 25 1989" );
      sscanf( dtm, "%s %s %d  %d", weekday, month, &day, &year );    //=====================
    
      printf("%s %d, %d = %s\n", month, day, year, weekday );
       
      return(0);
    }
    

二、今日做题记录

第一题

912.数组排序

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

1,使用函数

代码:

/**
 * Note: The returned array must be malloced, assume caller calls free().  
 */
int compar(const void*p1,const void*p2){
    return (*(int *)p1)-(*(int *)p2);
}
int* sortArray(int* nums, int numsSize, int* returnSize){
    // int compar(const *p1,const *p2);
    int *result = (int *)malloc(sizeof(int)*numsSize);  //因为Note:所以新申请了数组空间
    int i;
    for(i=0;i<numsSize;i++){
        result[i] = nums[i];
    }
    *returnSize = numsSize;
    qsort(result,numsSize,sizeof(int),compar);
    return result;
}

2,使用原地排序算法(不使用函数qsort)能排序但是效率不高,超时了哈哈

是一种排序算法,之所以叫原地,就是然空间复杂度保持我常数级O(1)。

[插入排序](https://blog.csdn.net/weixin_44373236/article/details/113888256)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LOomFYbl-1639469884190)(D:\Qian\Picture\插入排序图解.png)]

int* sortArray(int* nums, int numsSize, int* returnSize){
    int j;
    for(j=1;j<numsSize;j++){
        int i = j-1;
        int key = nums[j];
        while(i>=0&&nums[i]>key){
            nums[i+1] =nums[i];
            i--;
        }
        nums[i+1]=key;
    }
    *returnSize = numsSize;
    return nums;
}
第二题

169.多数元素

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

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

题解

int compar(const void *p1, const void *p2){
    return (*(int *)p1)-(*(int *)p2);
}
int majorityElement(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),compar);
    return nums[numsSize/2];
}
第三题

217.存在重复元素

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

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

int cmp(const void *a, const void *b) {
    return (*(int *)a) - (*(int *)b);
}

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

java 利用Set<> 数据结构

    public boolean containsDuplicate(int[] nums) {
        
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i <nums.length;i++){
            if (!set.add(nums[i])){
                return true;
            }
        }
        return false;
    }
第四题

164.最大间距

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

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

int cmp(const void *a, const void *b) {
    return (*(int *)a) - (*(int *)b);
}
int getMax(int a,int b){
    return a>b?a:b;
}
int maximumGap(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),cmp);
    int i,result;
    result =0;
    for (i=1;i<numsSize;i++){
        result = getMax(result,nums[i]-nums[i-1]) ;
    }
    return result;
}
第五题

905.按奇偶排序数组

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

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

int Qua(int x) {
    return x & 1;
}

int cmp(const void *a, const void *b) {
    return Qua(*(int *)a) - Qua(*(int *)b);
}

int* sortArrayByParity(int* nums, int numsSize, int* returnSize){
    int i;
    qsort(nums, numsSize, sizeof(int), cmp);              // (3)
    *returnSize = numsSize;                              // (4)
    return nums;
}

第六题

530.最小时间差

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

int cmp(const void *a, const void *b) {
    return (*(int *)a) - (*(int *)b);
}
int getMain(int a,int b){
    return a<b?a:b;
}

int findMinDifference(char ** timePoints, int timePointsSize){
    int *result = (int *)malloc(sizeof(int)*timePointsSize);
    int i,a,b,ans = 1440;
    for(i=0;i<timePointsSize;i++){
        sscanf(timePoints[i],"%d:%d",&a,&b);
        printf("%d:%d",a,b);
        result[i] = a*60+b;
    }
    qsort(result,timePointsSize,sizeof(int),cmp);
    for(i = 1;i<timePointsSize;i++){
        ans = getMain(ans,result[i]-result[i-1]);
    }
    ans = getMain(ans,result[0]-result[timePointsSize-1]+1440);
    return ans;
}
第七题

976.三角形的最大周长

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

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

int cmp(const void *a, const void *b) {
    return (*(int *)a) - (*(int *)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-2]+nums[i-1]>nums[i]){
            return nums[i-2]+nums[i-1]+nums[i];
        }
    }
    return 0;
}
第八题

881.救生艇

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

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

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

int cmp(const void *a, const void *b) {
    return (*(int *)a) - (*(int *)b);
}
int numRescueBoats(int* people, int peopleSize, int limit){

    qsort(people,peopleSize,sizeof(int),cmp);
    int l,r,ans;
    l = 0;
    r = peopleSize-1;
    ans = 0;
    while(l<=r){
        if(l == r){
            return ans++;
        }
        if (people[l]+people[r]>limit){
            ans++;
            r--;
        }else{
            ans ++;
            l++;
            r--;
        }
    }
    return ans;
}

三、今日收获

1,系统函数qsort()函数的使用,及其中比较函数的使用。

2,N级指针,及在数据结构对应多维数组的应用。

3,sscanf()解析字符串的应用。

4,void * 无类型指针的表示,及应用。

5,求一些特殊结果时,对有序数组的应用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值