【万人千题】《算法零基础100讲》(第37讲) 排序进阶 - 快速排序【题解】

目录

传送门

 课后习题

最小时间差 

有序数组得平方

救生艇


传送门

《算法零基础100讲》(第37讲) 排序进阶 - 快速排序icon-default.png?t=LA92https://blog.csdn.net/WhereIsHeroFrom/article/details/121551692

今天知识点是排序算法中的快速排序,应该是目前最快的一种排序算法了(桶排别来),学习了有英雄哥的代码按照自己的理解写了注释

在循环那里可能不好理解,自己多画几组小数据,会好理解得多

void swap(int *a,int *b){
    int t = *a;
    *a = *b;
    *b = t;
}
int partition(int *nums,int l,int r){
    int i,j,pivox;
    int idx = rand()%(r-l+1) + l;//随机选择一个基准,rand函数%n,就是随机生成0~n-1的数,最后加上 l
    pivox = nums[idx];         //记录基准值
    swap(&nums[l],&nums[idx]); //将基准值和左边界交换
    i = j = l+1;    //左边界现在已经是基准值了,所以从l+1开始
    while(i <= r){  //只要还没超出有边界继续
        if(nums[i] < pivox){     //指针i负责寻找比基准值小的数
            swap(&nums[i],&nums[j]);//找到了交换
            ++j;        //指针后移
        }
        ++i;
    }
    swap(&nums[l],&nums[j-1]); 
    return j-1;
}
void QuickSort(int *nums,int l,int r){
    if(l >= r)
        return;
    int mid = partition(nums,l,r);
    QuickSort(nums,l,mid-1);
    QuickSort(nums,mid+1,r);
}

 课后习题

最小时间差 

               最小时间差icon-default.png?t=LA92https://leetcode-cn.com/problems/minimum-time-difference/

题目描述:

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

思路:将时间转化成分钟并排序,然后遍历(注意还需要与第一个和最后一个得差值比较)

void swap(int *a,int *b){
    int t = *a;
    *a = *b;
    *b = t;
}
int partition(int *nums,int l,int r){
    int i,j,pivox;
    int idx = rand()%(r-l+1) + l;
    pivox = nums[idx];         
    swap(&nums[l],&nums[idx]); 
    i = j = l+1;    
    while(i <= r){  
        if(nums[i] < pivox){     
            swap(&nums[i],&nums[j]);
            ++j;        
        }
        ++i;
    }
    swap(&nums[l],&nums[j-1]); 
    return j-1;
}
void QuickSort(int *nums,int l,int r){
    if(l >= r)
        return;
    int mid = partition(nums,l,r);
    QuickSort(nums,l,mid-1);
    QuickSort(nums,mid+1,r);
}
int trans(char *Time){
    return ((Time[0]-'0')*10+Time[1]-'0')*60 + ((Time[3]-'0')*10+Time[4]-'0');
}
int min(int a,int b){
    return a<b ? a:b;
}

int findMinDifference(char ** timePoints, int timePointsSize){
    const int n = timePointsSize;
    int minute[n];      //      用来存放转化成分钟的数据
    memset(minute,0,sizeof(minute));       //初始化数组
    int i,j,ans = INT_MAX;
    for(i=0;i<timePointsSize;++i){  
        minute[i] = trans(timePoints[i]);       //将每个时间都转化成分钟
    }
    // qsort(minute,n,sizeof(int),cmp);
    QuickSort(minute,0,n-1);        //对序列排序
    for(i=1;i<n;++i){
        ans = min(ans,(minute[i]-minute[i-1]));         //寻找最小两个时间差
    }
    ans = min(ans,(24*60+minute[0] - minute[n-1]));      //注意最后和第一个比较,因为是24小时制
                                                    //比如00:00和23:59是相差一分钟
    return ans;
}

有序数组得平方

有序数组的平方icon-default.png?t=LA92https://leetcode-cn.com/problems/squares-of-a-sorted-array/

题目描述:

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

思路:排序后找到第一个非负数,双指针一个往前走,一个往后推,分别将绝对值小得先放入

int* sortedSquares(int* nums, int numsSize, int* returnSize){
    int nonnegative,i,j,k=0;
    for(i=0;i<numsSize;++i){            //找到第一个非负数
        if(nums[i] >= 0){
            nonnegative = i;
            break;
        }
    }
    *returnSize = numsSize;
    int *res = (int*)malloc(sizeof(int)*numsSize); //开辟一个新数组,用于返回
    i = nonnegative-1;j = nonnegative;      // 两个指针一个从第一个负数往前,一个从第一个非负数往后
    while(i >=0 && j <numsSize){            //当有一个到达边界退出
        if(nums[i]+nums[j] > 0){           // 将绝对值小的放入结果数组,并移动对应指针至下一位置
            res[k++] = nums[i]*nums[i];
            --i;
        }
        else{
            res[k++] = nums[j]*nums[j];
            ++j;
        }
    }
    while(i >= 0){                    //将剩余元素放入结果数组
        res[k++] = nums[i]*nums[i];
        --i;
    }
    while(j < numsSize){
        res[k++] = nums[j]*nums[j];
        ++j;
    }
    return res;
}

救生艇

救生艇icon-default.png?t=LA92https://leetcode-cn.com/problems/boats-to-save-people/

 题目描述:

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

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

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

思路:排序,双指针,分别指向当前最轻和最重,如果超重了,就重的单开一艘船(一艘船最多坐两个人)

 

bool cmp(void *a,void *b){
    return *(int*)a > *(int*)b;
}
int numRescueBoats(int* people, int peopleSize, int limit){
    qsort(people,peopleSize,sizeof(int),cmp);  //排序
    int i=0,j=peopleSize-1,ans = 0;       //分别指向剩余的最轻和最重
    while(i <= j){          
        if(people[i] + people[j] > limit){    //如果相加 > limit 则最重的单开一条船
            --j;
        }
        else {               //否则共开一条船
            ++i;
            --j;
        }
        ++ans;
    }
    return ans;
}

今天打卡完成!! 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周日加一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值