力扣刷题——排序

  1. 判断能否形成等差数列
给你一个数字数组 arr
如果可以重新排列数组形成等差数列,请返回 true ;否则,返回 false

示例 1:
输入:arr = [3,5,1]
输出:true
解释:对数组重新排序得到 [1,3,5] 或者 [5,3,1]
任意相邻两项的差分别为 2 或 -2 ,可以形成等差数列。

示例 2:
输入:arr = [1,2,4]
输出:false
解释:无法通过重新排序得到等差数列。

思路1数组排序+逐项验证
最直观的思路就是,先把数组排序
然后一次遍历挨个判断两两之间的间距是否相等
如果相等,则为等差,否则不符合条件

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

bool canMakeArithmeticProgression(int* arr, int arrSize) {
   
    if (2 == arrSize)return true;
    qsort(arr, arrSize, sizeof(int), cmpfun); //快排
    int gap = arr[1] - arr[0];	//记录两个数之间的差值
    for (size_t i = 2; i < arrSize; i++) {
   	//逐项判断
        if (arr[i] - arr[i - 1] != gap)
            return false;
    } return true;
}

女少口啊
思路2验证等差求和公式
我们易知等差数列的求和公式为 (首项+尾项)x项数÷2
而首项和尾项之和自然就是最小项和最大项之和(显而易见)
所以,我们其实不需要对数组进行排序
我们只需要一次遍历数组,得到:最小项、最大项、总和
就可以根据上述求和公式验证是否为等差数列

bool canMakeArithmeticProgression(int* arr, int arrSize) {
   
    double sum = 0.0;
    int max = -99999999, min = +99999999;
    for (size_t i = 0; i < arrSize; sum += arr[i++]) {
   
        if (arr[i] > max)max = arr[i];
        if (arr[i] < min)min = arr[i];
    } return ((min + max) * arrSize / 2.0 == sum);
}

.
.
.

  1. 数组的相对排序
给你两个数组,arr1 和 arr2,
arr2 中的元素各不相同
arr2 中的每个元素都出现在 arr1 中
对 arr1 中的元素进行排序,
使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。
未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。

示例:
输入:arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
输出:[2,2,2,1,4,3,3,9,6,7,19]

提示:
arr1.length, arr2.length <= 1000
0 <= arr1[i], arr2[i] <= 1000
arr2 中的元素 arr2[i] 各不相同
arr2 中的每个元素 arr2[i] 都出现在 arr1 中

思路桶排序&哈希
这道题的思路源自网友。
首先需要知道桶排序这个东西,如果不知道的话,移步这个网站了解一下:
点击链接进行跳转: 桶排序快速扫盲

对桶排序有了个大概了解之后,这道题大概就有了思路了。
而且,观察题目所给的提示,也容易受到启发从而想到桶排序

具体思路是:
新建一个bucket数组,然后仿造桶排序,
以arr1的元素作为下标,对bucket中相应元素进行递增(有点类似于哈希)
紧接着对arr2进行遍历,
以arr2的元素作为下标,把bucket中符合条件的元素(即在arr1中出现过的元素)的下标取出来赋值到arr1
注意,在我们把arr1的元素“安排”进bucket之后,arr1已经是废物一个了
最后我们再把bucket中剩下的元素(也就是只在arr1中出现的元素)按照桶排序输出到arr1的末尾
Done!

int*
relativeSortArray(int* arr1, int arr1Size, 
                    int* arr2, int arr2Size, 
                    int* returnSize) {
   
    *returnSize = arr1Size;
    int bucket[1001] = {
    0 };   //定义一个桶
    for 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值