📅  最后修改于: 2023-12-03 15:26:28.629000             🧑  作者: Mango
在一个由非负整数构成的数组中,找到一个最长的子数组,使得子数组中至少有两个元素,且所有元素的最大公约数(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
函数。