📜  最长子数组的长度,长度至少为2,最大GCD(1)

📅  最后修改于: 2023-12-03 15:26:28.629000             🧑  作者: Mango

最长子数组的长度,长度至少为2,最大GCD

介绍

在一个由非负整数构成的数组中,找到一个最长的子数组,使得子数组中至少有两个元素,且所有元素的最大公约数(GCD)相同。返回这个最长子数组的长度。

解法

我们可以枚举所有可能的GCD,然后对于每个GCD,找到所有GCD为该值的子数组中的最长子数组长度。最后取所有长度的最大值即为所求。

具体实现中,我们可以用哈希表记录每个元素所在子数组的最大的GCD值。对于每个GCD,我们可以用双指针法找到所有GCD为该值的子数组中的最长子数组长度。

时间复杂度为 $O(n \sqrt{A})$,其中 $n$ 是数组长度,$A$ 是数组中元素的最大值。

示例

输入: [6,10,3,9,12]

输出: 3

解释: [6,9,12] 是输入数组中最长的子数组,且它们的最大公约数为 3。

代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n = nums.size();
        int ans = 0;
        unordered_map<int, int> mp;

        for (int i = 0; i < n; ++i) {
            mp[nums[i]] = max(mp[nums[i]], 1);
            for (auto it = mp.begin(); it != mp.end(); ++it) {
                int g = gcd(it->first, nums[i]);
                if (g > 1) {
                    mp[g] = max(mp[g], it->second + 1);
                }
            }
        }

        for (auto it = mp.begin(); it != mp.end(); ++it) {
            if (it->second > 1) {
                ans = max(ans, it->second);
            }
        }

        return ans;
    }
};

注:上述代码中的 gcd 函数是一个辗转相除法求最大公约数的实现,可以自己手动实现或者使用标准库的 __gcd 函数。