这题最简单的方式就是排序中间段然后再去判断,这种方法就不讲了。
下面这种方法的思路是这样的:
首先扫描中间段,然后找出最大和最小元素,然后算出他们的公差,之后扫描元素的时候直接去判断当前元素是第几个元素,然后有没有出现过,出现超过两次则不符合。中间有些小细节,当我们的公差和不能整除当前元素个数的时候我们也认为是不能组成等差数组,还有就是公差是0的时候的一个特殊处理。
c++版本的代码如下:
class Solution {
public:
vector<bool> checkArithmeticSubarrays(vector<int>& nums, vector<int>& l, vector<int>& r) {
int len = l.size();
vector<bool> ans;
for(int i = 0 ; i < len ; i++)
{
int theMin = INT_MAX;
int theMax = INT_MIN;
for(int j = l[i] ; j <= r[i] ; j++)
{
//找出区间最大最小的数
theMin = min(theMin,nums[j]);
theMax = max(theMax, nums[j]);
}
//计算公差
if((theMax - theMin) % (r[i] - l[i])) //公差不能整除长度不行
{
ans.push_back(false);
continue;
}
int diff = (theMax - theMin) / (r[i] - l[i]);
//再次扫描
vector<int> vis(r[i]-l[i]+1,0);
bool temp = true;
for(int j = l[i] ; j <= r[i] ; j++)
{
if(diff == 0)
{
if(nums[j]!=theMin)
{
temp = false;
break;
}
}
else{
int dis = nums[j] - theMin;
if(diff && dis % diff) //说明当前数不再等差数列里面
{
temp=false;
break;
}
vis[dis / diff]++;
if(vis[dis / diff]>1)
{
temp=false;
break;
}
}
}
ans.push_back(temp);
}
return ans;
}
};