题目是LeetCode第196场周赛的第一题,链接:1502. 判断能否形成等差数列。具体描述为:给你一个数字数组arr。如果一个数列中,任意相邻两项的差总等于同一个常数,那么这个数列就称为等差数列。如果可以重新排列数组形成等差数列,请返回true;否则,返回false。
示例1:
输入:arr = [3,5,1]
输出:true
解释:对数组重新排序得到 [1,3,5] 或者 [5,3,1] ,任意相邻两项的差分别为 2 或 -2 ,可以形成等差数列。
示例2:
输入:arr = [1,2,4]
输出:false
解释:无法通过重新排序得到等差数列。
没啥难度,直接排序然后判断相邻两个数之差是否为公差就行了。时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度为 O ( l o g n ) O(logn) O(logn)(排序用到的递归栈)。
JAVA版代码如下:
class Solution {
public boolean canMakeArithmeticProgression(int[] arr) {
if (arr.length <= 2) {
return true;
}
Arrays.sort(arr);
int num = arr[1] - arr[0];
for (int i = 2; i < arr.length; ++i) {
if (arr[i] - arr[i - 1] != num) {
return false;
}
}
return true;
}
}
提交结果如下:
Python版代码如下:
class Solution:
def canMakeArithmeticProgression(self, arr: List[int]) -> bool:
arr.sort()
if len(arr) <= 2:
return True
num = arr[1] - arr[0]
for i in range(2, len(arr)):
if arr[i] - arr[i - 1] != num:
return False
return True
提交结果如下:
另外还有 O ( n ) O(n) O(n)的做法,就是先找到数组的最大最小值,先假设是个等差数列,那么就可以求出公差来,然后可以恢复出从最小值一直到最大值的等差数列(有可能跟原数组不一样,这时说明原数组构成不了等差数列),判断这些数是否在原来的数组中(用set去做)即可。
JAVA版代码如下:
class Solution {
public boolean canMakeArithmeticProgression(int[] arr) {
if (arr.length <= 2) {
return true;
}
Set<Integer> set = new HashSet<>();
int maxNum = Integer.MIN_VALUE, minNum = Integer.MAX_VALUE;
for (int a : arr) {
minNum = Math.min(minNum, a);
maxNum = Math.max(maxNum, a);
set.add(a);
}
if (maxNum == minNum) {
return true;
}
if ((maxNum - minNum) % (arr.length - 1) != 0) {
return false;
}
int diff = (maxNum - minNum) / (arr.length - 1);
for (int i = 1; i < arr.length - 1; ++i) {
if (!set.contains(minNum + i * diff)) {
return false;
}
}
return true;
}
}
提交结果如下:
本文介绍了一种判断数组是否能通过重新排序形成等差数列的算法,提供了JAVA和Python实现,包括O(nlogn)排序解决方案及O(n)优化方法。

654

被折叠的 条评论
为什么被折叠?



