给你一个数字数组 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);
}
.
.
.
给你两个数组,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