目录
传送门
《算法零基础100讲》(第37讲) 排序进阶 - 快速排序https://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);
}
课后习题
最小时间差
最小时间差https://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;
}
有序数组得平方
有序数组的平方https://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;
}
救生艇
救生艇https://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;
}
今天打卡完成!!