微软面试题:求整数随机数构成的数组中找到长度大于=3的最长的等差数列

本文介绍了一种寻找数组中最长等差数列的方法,通过枚举数列的前两个元素并逐步验证后续元素是否符合等差条件,最终确定最长等差数列。该算法的时间复杂度为O(n^3)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里用最简单的思路,时间复杂度为O(n^3)


思路:我们知道任意取2个元素,都能构成一个长度为2的等差数列,比如:a,b就等构成一个长度为2的,首元素为a,差为b-a的等差数列。

但是三个数:a,b,c(有序)就不一定了,因为c-b和b-a未必相等。


所以我们可以穷举出数列的前2个元素a[i], a[j],因为2个数必然构成一个等差数列,差为diff = a[j]-a[i]。然后j后面的元素中,找到一个a[k]使得a[k] = a[j]+diff,然后后在k后面找到a[n] = a[k]+diff,最后知道到达数组尾部。

我们可以定义一个变量length统计这个数列的最大长度,并且和已知的最大长度max比较,如果比Max大,就更新max = length。

同样我们可以定义一个stack来记录当前这个数列中的元素,并且定义另一个栈maxstack记录目前已知的最大长度的数列所包含的元素。

当遇到length>max的话,那说明maxstack也要重新赋值,所以我们就清空maxstack里原来的记录,用当前stack中记录的最长数列,去更新maxstack.


#include "stdafx.h" 
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;

void clear(stack<int> &ss)//清空栈
{
	while(ss.size()>0)
		ss.pop();
}
void copy(stack<int> ss,stack<int> &max)//用栈ss的内容去赋值max栈
{
	while(!ss.empty())
	{
		max.push(ss.top());
		ss.pop();
	}
}
int longest(int a[], int len)//求最长的等差数列
{
     sort(a,a+len);//先对数组进行排序
     unsigned int max = 1;//记录最长的等差数列的长度
     stack<int> ss;//记录当前等差数列的元素
     stack<int> maxstack;//记录目前已知的最长等差数列的元素
     for(int i=0;i<len;i++)//等差数列的第一个元素
     {
             ss.push(a[i]);//第一个元素入栈
             for(int j=i+1;j<len;j++)//等差数列的第二个元素
             {
                     ss.push(a[j]);//第二个元素入栈
                     int diff = a[j] - a[i];//公差
                     int base = a[j];//这个是查找下一个元素用
                     //int length = 2;
                     for(int k = j+1;k<len;k++)
                     {
                             if(a[k] == (base+diff))//如果当前等差数列的下一个元素是a[k]
							{
                                     ss.push(a[k]);//a[k]入栈
                                     //length++;
                                     base = a[k];//更新base为当前元素,查找下一个元素base+diff即可
                             }       
                     }
                     if(ss.size()>max)//如果当前得到的最长数列,比已知的最长数列长
                     {
                                   max = ss.size();//更新最长长度
                                   clear(maxstack);//清空maxstack
								   copy(ss,maxstack);//更新最长数列的所有元素
                     }
                     while(ss.size()>1)//重新选择第二个元素a[j],所以需要pop所有元素只留下第一个
                     {
                                       ss.pop();
                     }
             }
             clear(ss);//清空ss,重新选择第一个元素a[i]
     }
     while(maxstack.size()>0)//输出最长的数列
     {
        cout<<maxstack.top()<<" ";
        maxstack.pop();
     }
     cout<<endl;
     return max;
}

int main()
{
    int a[] = {1,3,0,5,-1,-6};  
    int len = sizeof(a)/sizeof(int);
    cout<<longest(a,len)<<endl;
    getchar();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值