Easy
题目描述
如果一个数字序列中任意两个连续元素之间的差值都相同,那么这个序列就被称为等差数列。
给定一个数字数组 arr,如果能够重新排列数组中的元素形成一个等差数列,则返回 true;否则返回 false。
示例 1:
输入:arr = [3,5,1]
输出:true
解释:我们可以重新排列元素为 [1,3,5] 或者 [5,3,1],连续元素之间的差值分别为 2 和 -2。
示例 2:
输入:arr = [1,2,4]
输出:false
解释:无法重新排列形成等差数列。
约束条件:
2 <= arr.length <= 1000-10^6 <= arr[i] <= 10^6
提示:
- 任何有效的等差数列都是有序的
- 对数组排序,然后检查所有连续元素的差值是否相等
解题思路
解题思路
这道题的核心思想是:等差数列在排序后,任意两个相邻元素的差值都相等。
方法一:排序 + 检查差值(推荐)
思路分析:
- 将数组排序,这样如果能构成等差数列,排序后的数组就是一个等差数列
- 计算排序后数组中相邻元素的差值
- 检查所有相邻元素的差值是否都相等
这种方法简单直观,时间复杂度主要由排序决定。
方法二:数学方法
还可以利用等差数列的数学性质:如果数组能构成等差数列,那么:
- 公差 = (最大值 - 最小值) / (数组长度 - 1)
- 且公差必须是整数
- 排序后检查是否符合等差数列规律
但考虑到实现复杂度和可读性,方法一更加直观易懂。
时间复杂度: O(n log n),主要是排序的复杂度 空间复杂度: O(1),只使用常数额外空间
代码实现
class Solution {
public:
bool canMakeArithmeticProgression(vector<int>& arr) {
sort(arr.begin(), arr.end());
int diff = arr[1] - arr[0];
for (int i = 2; i < arr.size(); i++) {
if (arr[i] - arr[i-1] != diff) {
return false;
}
}
return true;
}
};
class Solution:
def canMakeArithmeticProgression(self, arr: List[int]) -> bool:
arr.sort()
diff = arr[1] - arr[0]
for i in range(2, len(arr)):
if arr[i] - arr[i-1] != diff:
return False
return True
public class Solution {
public bool CanMakeArithmeticProgression(int[] arr) {
Array.Sort(arr);
int diff = arr[1] - arr[0];
for (int i = 2; i < arr.Length; i++) {
if (arr[i] - arr[i-1] != diff) {
return false;
}
}
return true;
}
}
var canMakeArithmeticProgression = function(arr) {
arr.sort((a, b) => a - b);
const diff = arr[1] - arr[0];
for (let i = 2; i < arr.length; i++) {
if (arr[i] - arr[i-1] !== diff) {
return false;
}
}
return true;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n log n) | 排序需要 O(n log n),遍历检查需要 O(n) |
| 空间复杂度 | O(1) | 只使用常数额外空间(原地排序) |
相关题目
- . Arithmetic Subarrays (Medium)