随机数中寻找长度大于3的等差数列


这部分转自网上:

输出等差数列由小到大?如果没有符合条件的就输出“NO”。

例如: 输入[1,3,0,5,-1,6] ,输出[-1,1,3,5] 。

要求:时间复杂度,空间复杂度尽量小

解体思路:设随机数为a[],首先排序,

(1)枚举两个数,作为数列中相邻的两个元素Ai,Ai+1,那么可求出等差d=Ai+1-Ai。于是Ai-1=Ai-d,Ai+2=Ai+1+d,因此可以在剩下的数寻找Ai-1,Ai+2是否存在,可以用一个set来维护查找,而数列最长可为n,查找次数最大为n,而查找复杂度为logn,总时间复杂度为O(n^3logn)。复杂度太高,不可取。

(2)动态规划求解。设f[i][j]为以a[i],a[j]结尾的等差数列的最长长度。那么

递归方程为:f[i][j]=max{f[k][i]+1,a[k]-a[i]==a[i]-a[j]},起始条件f[i][j]=1;伪代码如下:

for(int k =0; k <n; k++)

for(int i=k+1;i<n;i++)

for(int j=i+1;j<n;j++)

if(a[k]-a[i] == a[i]-a[j])

f[i][j] = (f[i][j]<f[k][i]+1?f[k][i]+1:f[i][j]);

而,最长长度为即为max{f[i][j]},即以a[i],a[j]结尾,通过一次查找即可求出是那些元素组成的解。复杂度O(n^3)。

(3)枚举等差,将所有差相同的数对(a,b),分别以a,以b作为key,另一个作为值,插入到两个map之中,然后解必然在某一个map之内。于是,枚举每一个map,进行删除操作,比如(a,b)那么下一个值为b+(b-a),前一个值为a-(b-a),分别到两个map中去查找,迭代之。复杂度O(n^2logn)。

依照方法2写出代码,复杂度O(n^3)

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>

using namespace std;

struct Node {
	Node(int i = 0, Node *l = NULL, Node *r = NULL) : data(i), left(l), right(r) {}
	Node *left;
	Node *right;
	int data;
};

int array[] = {1, 3, 0, 5, -1, 6};
const int size = sizeof array / sizeof *array;

int findLongDengCha(int *numbers, int size, vector<int> &result)
{
	sort(numbers, numbers + size);
	
	int maxCount = 2;
	int tempCount = 2;
	for(int i = 0; i < size - 1; i++) {
		for(int j = i + 1; j < size; j++) {
			int diff = numbers[j] - numbers[i];
			int nextNumber = diff + numbers[j];
			tempCount = 2;
			for(int k = j + 1; k < size; k++) {
				if(numbers[k] == nextNumber) {
					tempCount++;
				}
				nextNumber += diff;
			}

			if(tempCount > maxCount)
				maxCount = tempCount;
		}
	}

	return maxCount;
}

void main()
{
	vector<int> result;

	int count = findLongDengCha(array, size, result);

	if(count >= 3)
		cout << "count = " << count << endl;
	else
		cout << "find none" << endl;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值