今天是打卡的第37天,今天的难度一般般,赶紧写写写篇python爬虫试试水0.0 知识点在:
《算法零基础100讲》(第37讲) 排序进阶 - 快速排序
c语言中常见的排序方式
基于分治的思想,利用哨兵作为比较的点,将大于哨兵点
void swap(int *a, int *b){
//交换节点
if(a == b) return; //这是个大坑 如果a和b是同一个元素会变成0
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
int Partition(int *a, int l, int r){
int i = l + 1, j = l + 1, idx = l + (r - l) /2, pivox = a[idx]; //i 和j用于划分 idx选择中间元素进行分治
swap(&a[l], &a[idx]); //将idx暂存到l的位置
while(i <= r) //进行交换 使j前元素小于idx位置
if(a[i++] < pivox)
swap(&a[i-1],&a[j++]);
swap(&a[l],&a[j-1]);//将idx元素放回
return j - 1;//返回idx的位置
}
void QuickSort(int *a,int l,int r){
if(l < r){
int mid = Partition(a,l,r);
QuickSort(a,l,mid - 1);//排序左边
QuickSort(a,mid + 1,r);//排序右边
}
}
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;
}
977. 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
解题思路1
先全部平方,然后排序就好了?应该是英雄哥的本意吧?
void swap(int *a, int *b){
if(a == b) return;
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
int Partition(int *a, int l, int r){
int i = l + 1, j = l + 1, idx = l + (r - l) /2, pivox = a[idx];
swap(&a[l], &a[idx]);
while(i <= r)
if(a[i++] < pivox)
swap(&a[i-1],&a[j++]);
swap(&a[l],&a[j-1]);
return j - 1;
}
void QuickSort(int *a,int l,int r){
if(l < r){
int mid = Partition(a,l,r);
QuickSort(a,l,mid - 1);
QuickSort(a,mid + 1,r);
}
}
int* sortedSquares(int* nums, int numsSize, int* returnSize){
int* ans = malloc(sizeof(int) * numsSize);
for(int i = 0;i < numsSize;i++)//转化为平方
ans[i] = nums[i] * nums[i];
*returnSize = numsSize;
QuickSort(ans,0,numsSize - 1);//快排不解释
return ans;
}
解题思路2
上面太慢了,其实如果从后往前更新数组,那么最大值一定是最小值的平方或者最大值的平方,搜一遍就出来了。有点归并的意思
int* sortedSquares(int* nums, int numsSize, int* returnSize){
int* ans = malloc(sizeof(int) * numsSize);
int l = 0, r = numsSize - 1,ansnum = numsSize;
*returnSize = numsSize;
while(ansnum){
//当没有插入完
if(nums[l] < 0) //只有小的小于0 才可能比后面的平方大
if(-nums[l] > nums[r]) ans[--ansnum] = nums[l] * nums[l],l++;
else ans[--ansnum] = nums[r] * nums[r],r--;
else ans[--ansnum] = nums[r] * nums[r],r--;
}
return ans;
}
870. 优势洗牌
给定两个大小相等的数组 A 和 B,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述。
返回 A 的任意排列,使其相对于 B 的优势最大化。
解题思路
这就是田忌赛马啊,找到一个最小的可以赢的值插入,如果怎么都赢不了,就选一个最小的,保证牺牲最小?
int cmp(int *a,int *b){
return *a > *b;}
int* advantageCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
qsort(nums1,nums1Size,sizeof(int),cmp);
int *ans = malloc(sizeof(int) * nums2Size);
bool hash[nums1Size];//标记元素是否使用
memset(hash,0,sizeof(hash));
for(int i = 0;i < nums2Size;i++){
int low = 0, high = nums1Size;
while(low < high){
//找到最小的元素
int mid = low + (high - low )/2;
if(nums1[mid] <= nums2[i]) low = mid + 1;
else high = mid;
}
while(high < nums1Size && hash[high]) //未被使用的最小元素
high++;
if(high == nums1Size){
//如果没找到就找个最小的
int k = 0;
while(hash[k]) k++;
hash[k] = 1;
ans[i] = nums1[k];
}
else {
//直接将找到的值当作解插入
hash[high] = 1;
ans[i] = nums1[high];
}
}
*returnSize = nums2Size;
return ans;
}
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;
}
今天的题感觉和快排的联系不是特别大,最近的作息还是有点乱,调,得调,好好调一调-.-