leetcode-判断能否形成等差数列

本文介绍了一种判断数组是否能通过重新排序形成等差数列的算法,提供了JAVA和Python实现,包括O(nlogn)排序解决方案及O(n)优化方法。

 题目是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;
    }
}

 提交结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值