找出最长的等差数列

这篇文章的来源:Finding Longest Arithmetic Progressions - by Jeff Erickson - je [email protected] - http://www.uiuc.edu/~je e

1 Introduction
This paper describes efficient algorithms for finding the longest arithmetic progression in a set of n integers. That is, given an array A[1 ... n] of integers, we wish to find the largest sequence of indices <i_0; i_1; ... ; i_k-1> such that A[i_j] - A[i_j-1] = A[i_1] - A[i_0] for all j. Note that the indices themselves need not form an arithmetic progression. There is an O(n log n) lower bound on the complexity of this problem in the algebraic decision tree model of computation [1], so without loss of generality, we assume that the input array A is sorted and free of duplicate elements.

2 Dynamic Programming
An interesting subproblem, which we call Average, is to determine whether the input contains a three-term arithmetic progression, or equivalently, if any array element is the average of two others. Average can be solved by the following simple O(n^2)-time algorithm. This is the fastest algorithm known. There is a matching O(n^2) lower bound in the 3-linear decision tree model, in which every decision depends on the sign of an affine combination of three or fewer input elements [4], so at least in that model, this algorithm is optimal.

Average(A[1...n]):
for j <- 2 to n - 1
	i <- j - 1
	k <- j + 1
	while (i >= 1 and k <= n)
		if A[i] + A[k] < 2A[j]
			k <- k + 1
		else if A[i] + A[k] > 2A[j]
			i <- i - 1
		else
			return True
return False

Average is closely related to the class of 3SUM-hard problems de ned by Gajentaan and Overmars [5]. A problem is 3sum-hard if there is a sub-quadratic reduction from the problem 3sum: Given a set A of n integers, are there elements a, b, c such that a + b + c = 0? It is not known whether Average is 3sum-hard. However, there is a simple linear-time reduction from Average to 3sum, whose description we omit. (Thus, 3sum-hard problems might better be called "Average-hard".) 

The longest arithmetic progression can be found in O(n^2) time using a dynamic programming algorithm similar to our algorithm for Average. The algorithm shown below computes only the length of the longest arithmetic progression; computing the actual progression requires only a few extra lines. When our algorithm terminates, L[i, j] stores the maximum length of an arithmetic progression whose first two terms are respectively A[i] and A[j]. Our algorithm can be described by a family of 3-linear decision trees, and the (n^2) lower bound for Average [4] implies that it is optimal in that model of computation.

LongestArithProg(A[1...n]):
L* <-  2
for j <- n - 1 downto 1
	i <- j - 1; k <- j + 1
	while (i >= 1 and k <= n)
		if A[i] + A[k] < 2A[j]
			k <- k + 1
		else if A[i] + A[k] > 2A[j]
			L[i, j] <- 2
			i <- i - 1
		else
			L[i, j] <- L[j, k] + 1
			L* <- max{L*, L[i,j] }
			i <- i - 1; k <- k + 1
	while i >= 1
		L[i, j] <- 2; i <- i - 1
	return L*
Theorem 1. The longest arithmetic progression in an n-element set can be found in time O(n^2), which is optimal in the 3-linear decision tree model of computation.

你可能感兴趣的:(找出最长的等差数列)