给定一组数字,找出将L ongest一个rithmetic P rogression(L-LAP)在它的L个ength。
例子:
set[] = {1, 7, 10, 15, 27, 29}
output = 3
The longest arithmetic progression is {1, 15, 29}
set[] = {5, 10, 15, 20, 25, 30}
output = 6
The whole set is in AP
为简单起见,我们假设给定的集合已排序。我们总是可以添加一个预处理步骤来首先对集合进行排序,然后应用以下算法。
一个简单的解决方案是将每一对都视为 AP 的前两个元素,并检查排序集中的剩余元素。要将所有对视为前两个元素,我们需要运行 O(n^2) 嵌套循环。嵌套循环里面,我们需要第三个环路直线会在一个rithmetic P rogression(AP)的多个元素。这个过程需要 O(n 3 ) 时间。
我们可以使用动态规划在 O(n 2 ) 时间内解决这个问题。为了了解 DP 解决方案,让我们首先讨论以下更简单问题的解决方案。
给定一个有序集合,求算术级数中是否存在三个元素
请注意,如果 AP 中有 3 个或更多元素,则答案为真,否则为假。
为了找到这三个元素,我们首先将一个元素固定为中间元素,然后搜索其他两个(一个小一个大)。我们从第二个元素开始,将每个元素固定为中间元素。对于要成为 AP 中间的元素 set[j],必须存在元素 ‘set[i]’ 和 ‘set[k]’ 使得 set[i] + set[k] = 2*set[j] 其中 0 <= i < j 和 j < k <=n-1。
如何有效地找到给定 j 的 i 和 k?我们可以使用以下简单算法在线性时间内找到 i 和 k。
- 将 i 初始化为 j-1,将 k 初始化为 j+1
- 在 i >= 0 和 k <= n-1 时执行以下操作
- 如果 set[i] + set[k] 等于 2*set[j],那么我们就完成了。
- 如果 set[i] + set[k] > 2*set[j],则递减 i(做 i–)。
- 否则,如果 set[i] + set[k] < 2*set[j],则增加 k(做 k++)。
以下是针对较简单问题的上述算法的 C++ 实现。
C
// The function returns true if there exist three elements in AP
// Assumption: set[0..n-1] is sorted.
// The code strictly implements the algorithm provided in the reference.
bool arithmeticThree(int set[], int n)
{
// One by fix every element as middle element
for (int j=1; j= 0 && k <= n-1)
{
if (set[i] + set[k] == 2*set[j])
return true;
(set[i] + set[k] < 2*set[j])? k++ : i--;
}
}
return false;
}
Javascript
Python3
# The function returns true if there exist three elements in AP
# Assumption: set[0..n-1] is sorted.
# The code strictly implements the algorithm provided in the reference.
def arithematicThree(set_,n):
# One by fix every element as middle element
for j in range(n):
# Initialize i and k for the current j
i,k=j-1,j+1
# Find if there exist i and k that form AP
# with j as middle element
while i>-1 and k
C++
// C++ program to find Length of the Longest AP (llap) in a given sorted set.
// The code strictly implements the algorithm provided in the reference.
#include
using namespace std;
// Returns length of the longest AP subset in a given set
int lenghtOfLongestAP(int set[], int n)
{
if (n <= 2) return n;
// Create a table and initialize all values as 2. The value of
// L[i][j] stores LLAP with set[i] and set[j] as first two
// elements of AP. Only valid entries are the entries where j>i
int L[n][n];
int llap = 2; // Initialize the result
// Fill entries in last column as 2. There will always be
// two elements in AP with last number of set as second
// element in AP
for (int i = 0; i < n; i++)
L[i][n-1] = 2;
// Consider every element as second element of AP
for (int j=n-2; j>=1; j--)
{
// Search for i and k for j
int i = j-1, k = j+1;
while (i >= 0 && k <= n-1)
{
if (set[i] + set[k] < 2*set[j])
k++;
// Before changing i, set L[i][j] as 2
else if (set[i] + set[k] > 2*set[j])
{ L[i][j] = 2, i--; }
else
{
// Found i and k for j, LLAP with i and j as first two
// elements is equal to LLAP with j and k as first two
// elements plus 1. L[j][k] must have been filled
// before as we run the loop from right side
L[i][j] = L[j][k] + 1;
// Update overall LLAP, if needed
llap = max(llap, L[i][j]);
// Change i and k to fill more L[i][j] values for
// current j
i--; k++;
}
}
// If the loop was stopped due to k becoming more than
// n-1, set the remaining entties in column j as 2
while (i >= 0)
{
L[i][j] = 2;
i--;
}
}
return llap;
}
/* Driver program to test above function*/
int main()
{
int set1[] = {1, 7, 10, 13, 14, 19};
int n1 = sizeof(set1)/sizeof(set1[0]);
cout << lenghtOfLongestAP(set1, n1) << endl;
int set2[] = {1, 7, 10, 15, 27, 29};
int n2 = sizeof(set2)/sizeof(set2[0]);
cout << lenghtOfLongestAP(set2, n2) << endl;
int set3[] = {2, 4, 6, 8, 10};
int n3 = sizeof(set3)/sizeof(set3[0]);
cout << lenghtOfLongestAP(set3, n3) << endl;
return 0;
}
Java
// Java program to find Length of the
// Longest AP (llap) in a given sorted set.
// The code strictly implements the
// algorithm provided in the reference.
import java.io.*;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int lenghtOfLongestAP(int set[], int n)
{
if (n <= 2) return n;
// Create a table and initialize all
// values as 2. The value ofL[i][j] stores
// LLAP with set[i] and set[j] as first two
// elements of AP. Only valid entries are
// the entries where j>i
int L[][] = new int[n][n];
// Initialize the result
int llap = 2;
// Fill entries in last column as 2.
// There will always be two elements in
// AP with last number of set as second
// element in AP
for (int i = 0; i < n; i++)
L[i][n - 1] = 2;
// Consider every element as second element of AP
for (int j = n - 2; j >= 1; j--)
{
// Search for i and k for j
int i = j -1 , k = j + 1;
while (i >= 0 && k <= n - 1)
{
if (set[i] + set[k] < 2 * set[j])
k++;
// Before changing i, set L[i][j] as 2
else if (set[i] + set[k] > 2 * set[j])
{
L[i][j] = 2; i--;
}
else
{
// Found i and k for j, LLAP with i and j as first two
// elements is equal to LLAP with j and k as first two
// elements plus 1. L[j][k] must have been filled
// before as we run the loop from right side
L[i][j] = L[j][k] + 1;
// Update overall LLAP, if needed
llap = Math.max(llap, L[i][j]);
// Change i and k to fill
// more L[i][j] values for current j
i--; k++;
}
}
// If the loop was stopped due
// to k becoming more than
// n-1, set the remaining
// entties in column j as 2
while (i >= 0)
{
L[i][j] = 2;
i--;
}
}
return llap;
}
// Driver program
public static void main (String[] args)
{
int set1[] = {1, 7, 10, 13, 14, 19};
int n1 = set1.length;
System.out.println ( lenghtOfLongestAP(set1, n1));
int set2[] = {1, 7, 10, 15, 27, 29};
int n2 = set2.length;
System.out.println(lenghtOfLongestAP(set2, n2));
int set3[] = {2, 4, 6, 8, 10};
int n3 = set3.length;
System.out.println(lenghtOfLongestAP(set3, n3)) ;
}
}
// This code is contributed by vt_m
Python 3
# Python 3 program to find Length of the
# Longest AP (llap) in a given sorted set.
# The code strictly implements the algorithm
# provided in the reference
# Returns length of the longest AP
# subset in a given set
def lenghtOfLongestAP(set, n):
if (n <= 2):
return n
# Create a table and initialize all
# values as 2. The value of L[i][j]
# stores LLAP with set[i] and set[j]
# as first two elements of AP. Only
# valid entries are the entries where j>i
L = [[0 for x in range(n)]
for y in range(n)]
llap = 2 # Initialize the result
# Fill entries in last column as 2.
# There will always be two elements
# in AP with last number of set as
# second element in AP
for i in range(n):
L[i][n - 1] = 2
# Consider every element as second
# element of AP
for j in range(n - 2, 0, -1):
# Search for i and k for j
i = j - 1
k = j + 1
while(i >= 0 and k <= n - 1):
if (set[i] + set[k] < 2 * set[j]):
k += 1
# Before changing i, set L[i][j] as 2
elif (set[i] + set[k] > 2 * set[j]):
L[i][j] = 2
i -= 1
else:
# Found i and k for j, LLAP with i and j
# as first two elements are equal to LLAP
# with j and k as first two elements plus 1.
# L[j][k] must have been filled before as
# we run the loop from right side
L[i][j] = L[j][k] + 1
# Update overall LLAP, if needed
llap = max(llap, L[i][j])
# Change i and k to fill more L[i][j]
# values for current j
i -= 1
k += 1
# If the loop was stopped due to k
# becoming more than n-1, set the
# remaining entties in column j as 2
while (i >= 0):
L[i][j] = 2
i -= 1
return llap
# Driver Code
if __name__ == "__main__":
set1 = [1, 7, 10, 13, 14, 19]
n1 = len(set1)
print(lenghtOfLongestAP(set1, n1))
set2 = [1, 7, 10, 15, 27, 29]
n2 = len(set2)
print(lenghtOfLongestAP(set2, n2))
set3 = [2, 4, 6, 8, 10]
n3 = len(set3)
print(lenghtOfLongestAP(set3, n3))
# This code is contributed by ita_c
C#
// C# program to find Length of the
// Longest AP (llap) in a given sorted set.
// The code strictly implements the
// algorithm provided in the reference.
using System;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int lenghtOfLongestAP(int []set,
int n)
{
if (n <= 2) return n;
// Create a table and initialize
// all values as 2. The value of
// L[i][j] stores LLAP with set[i]
// and set[j] as first two elements
// of AP. Only valid entries are
// the entries where j>i
int [,]L = new int[n, n];
// Initialize the result
int llap = 2;
// Fill entries in last column as 2.
// There will always be two elements
// in AP with last number of set as
// second element in AP
for (int i = 0; i < n; i++)
L[i, n - 1] = 2;
// Consider every element as
// second element of AP
for (int j = n - 2; j >= 1; j--)
{
// Search for i and k for j
int i = j - 1 , k = j + 1;
while (i >= 0 && k <= n - 1)
{
if (set[i] + set[k] < 2 * set[j])
k++;
// Before changing i, set L[i][j] as 2
else if (set[i] + set[k] > 2 * set[j])
{
L[i, j] = 2; i--;
}
else
{
// Found i and k for j, LLAP with
// i and j as first two elements
// is equal to LLAP with j and k
// as first two elements plus 1.
// L[j][k] must have been filled
// before as we run the loop from
// right side
L[i, j] = L[j, k] + 1;
// Update overall LLAP, if needed
llap = Math.Max(llap, L[i, j]);
// Change i and k to fill
// more L[i][j] values for current j
i--; k++;
}
}
// If the loop was stopped due
// to k becoming more than
// n-1, set the remaining
// entties in column j as 2
while (i >= 0)
{
L[i, j] = 2;
i--;
}
}
return llap;
}
// Driver Code
static public void Main ()
{
int []set1 = {1, 7, 10, 13, 14, 19};
int n1 = set1.Length;
Console.WriteLine(lenghtOfLongestAP(set1, n1));
int []set2 = {1, 7, 10, 15, 27, 29};
int n2 = set2.Length;
Console.WriteLine(lenghtOfLongestAP(set2, n2));
int []set3 = {2, 4, 6, 8, 10};
int n3 = set3.Length;
Console.WriteLine(lenghtOfLongestAP(set3, n3)) ;
}
}
// This code is contributed by Sach_Code
PHP
i
$L[$n][$n] = array(array());
$llap = 2; // Initialize the result
// Fill entries in last column as 2.
// There will always be two elements
// in AP with last number of set as
// second element in AP
for ($i = 0; $i < $n; $i++)
$L[$i][$n - 1] = 2;
// Consider every element as
// second element of AP
for ($j = $n - 2; $j >= 1; $j--)
{
// Search for i and k for j
$i = $j - 1;
$k = $j + 1;
while ($i >= 0 && $k <= $n - 1)
{
if ($set[$i] + $set[$k] < 2 * $set[$j])
$k++;
// Before changing i, set L[i][j] as 2
else if ($set[$i] + $set[$k] > 2 * $set[$j])
{
$L[$i][$j] = 2;
$i--; }
else
{
// Found i and k for j, LLAP with
// i and j as first two elements
// is equal to LLAP with j and k
// as first two elements plus 1.
// L[j][k] must have been filled
// before as we run the loop from
// right side
$L[$i][$j] = $L[$j][$k] + 1;
// Update overall LLAP, if needed
$llap = max($llap, $L[$i][$j]);
// Change i and k to fill more
// L[i][j] values for current j
$i--;
$k++;
}
}
// If the loop was stopped due to k
// becoming more than n-1, set the
// remaining entties in column j as 2
while ($i >= 0)
{
$L[$i][$j] = 2;
$i--;
}
}
return $llap;
}
// Driver Code
$set1 = array(1, 7, 10, 13, 14, 19);
$n1 = sizeof($set1);
echo lenghtOfLongestAP($set1, $n1),"\n";
$set2 = array(1, 7, 10, 15, 27, 29);
$n2 = sizeof($set2);
echo lenghtOfLongestAP($set2, $n2),"\n";
$set3 = array(2, 4, 6, 8, 10);
$n3 = sizeof($set3);
echo lenghtOfLongestAP($set3, $n3),"\n";
// This code is contributed by Sach_Code
?>
Javascript
C++
// C++ program to find Length of the
// Longest AP (llap) in a given sorted set.
#include
using namespace std;
// Returns length of the longest
// AP subset in a given set
int Solution(vector A)
{
int ans = 2;
int n = A.size();
if (n <= 2)
return n;
vector llap(n, 2);
sort(A.begin(), A.end());
for (int j = n - 2; j >= 0; j--)
{
int i = j - 1;
int k = j + 1;
while (i >= 0 && k < n)
{
if (A[i] + A[k] == 2 * A[j])
{
llap[j] = max(llap[k] + 1, llap[j]);
ans = max(ans, llap[j]);
i -= 1;
k += 1;
}
else if (A[i] + A[k] < 2 * A[j])
k += 1;
else
i -= 1;
}
}
return ans;
}
// Driver Code
int main()
{
vector a({ 9, 4, 7, 2, 10 });
cout << Solution(a) << endl;
return 0;
}
// This code is contributed by ashutosh450
Java
// Java program to find Length of the
// Longest AP (llap) in a given sorted set.
import java.util.*;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int Solution(int []A)
{
int ans = 2;
int n = A.length;
if (n <= 2)
return n;
int []llap = new int[n];
for(int i = 0; i < n; i++)
llap[i] = 2;
Arrays.sort(A);
for (int j = n - 2; j >= 0; j--)
{
int i = j - 1;
int k = j + 1;
while (i >= 0 && k < n)
{
if (A[i] + A[k] == 2 * A[j])
{
llap[j] = Math.max(llap[k] + 1, llap[j]);
ans = Math.max(ans, llap[j]);
i -= 1;
k += 1;
}
else if (A[i] + A[k] < 2 * A[j])
k += 1;
else
i -= 1;
}
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int []a = { 9, 4, 7, 2, 10 };
System.out.print(Solution(a) +"\n");
}
}
// This code is contributed by Rajput-Ji
Python
# Python program to find Length
# of the Longest AP (llap) in a given sorted set.
# Returns length of the longest AP subset in a given set
class Solution:
def Solve(self, A):
ans = 2
n= len(A)
if n<=2 :
return n
llap = [2]*n
A.sort()
for j in range(n-2, -1, -1):
i= j-1
k= j+1
while(i>=0 and k
C#
// C# program to find Length of the
// longest AP (llap) in a given sorted set.
using System;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int Solution(int []A)
{
int ans = 2;
int n = A.Length;
if (n <= 2)
return n;
int []llap = new int[n];
for(int i = 0; i < n; i++)
llap[i] = 2;
Array.Sort(A);
for (int j = n - 2; j >= 0; j--)
{
int i = j - 1;
int k = j + 1;
while (i >= 0 && k < n)
{
if (A[i] + A[k] == 2 * A[j])
{
llap[j] = Math.Max(llap[k] + 1, llap[j]);
ans = Math.Max(ans, llap[j]);
i -= 1;
k += 1;
}
else if (A[i] + A[k] < 2 * A[j])
k += 1;
else
i -= 1;
}
}
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int []a = { 9, 4, 7, 2, 10 };
Console.Write(Solution(a) +"\n");
}
}
// This code is contributed by Rajput-Ji
Javascript
有关完整的运行程序,请参见此处。
如何将上述解决方案扩展为原始问题?
上面的函数返回一个布尔值。原问题的所需的输出是L ongest甲rithmetic P rogression(LLAP),该整数值L的ength。如果给定的集合有两个或更多元素,则 LLAP 的值至少为 2(为什么?)。
这个想法是创建一个二维表 L[n][n]。该表中的条目 L[i][j] 存储 LLAP,其中 set[i] 和 set[j] 作为 AP 的前两个元素且 j > i。表格的最后一列总是 2(为什么 – 见 L[i][j] 的含义)。表格的其余部分从右下角到左上角填充。为了填充表格的其余部分,首先固定 j(AP 中的第二个元素)。 i 和 k 被搜索一个固定的 j。如果找到 i 和 k 使得 i、j、k 形成 AP,则 L[i][j] 的值设置为 L[j][k] + 1。注意 L[j] 的值[k] 之前必须已填充,因为循环从右列到左列遍历。
下面是动态规划算法的实现。
C++
// C++ program to find Length of the Longest AP (llap) in a given sorted set.
// The code strictly implements the algorithm provided in the reference.
#include
using namespace std;
// Returns length of the longest AP subset in a given set
int lenghtOfLongestAP(int set[], int n)
{
if (n <= 2) return n;
// Create a table and initialize all values as 2. The value of
// L[i][j] stores LLAP with set[i] and set[j] as first two
// elements of AP. Only valid entries are the entries where j>i
int L[n][n];
int llap = 2; // Initialize the result
// Fill entries in last column as 2. There will always be
// two elements in AP with last number of set as second
// element in AP
for (int i = 0; i < n; i++)
L[i][n-1] = 2;
// Consider every element as second element of AP
for (int j=n-2; j>=1; j--)
{
// Search for i and k for j
int i = j-1, k = j+1;
while (i >= 0 && k <= n-1)
{
if (set[i] + set[k] < 2*set[j])
k++;
// Before changing i, set L[i][j] as 2
else if (set[i] + set[k] > 2*set[j])
{ L[i][j] = 2, i--; }
else
{
// Found i and k for j, LLAP with i and j as first two
// elements is equal to LLAP with j and k as first two
// elements plus 1. L[j][k] must have been filled
// before as we run the loop from right side
L[i][j] = L[j][k] + 1;
// Update overall LLAP, if needed
llap = max(llap, L[i][j]);
// Change i and k to fill more L[i][j] values for
// current j
i--; k++;
}
}
// If the loop was stopped due to k becoming more than
// n-1, set the remaining entties in column j as 2
while (i >= 0)
{
L[i][j] = 2;
i--;
}
}
return llap;
}
/* Driver program to test above function*/
int main()
{
int set1[] = {1, 7, 10, 13, 14, 19};
int n1 = sizeof(set1)/sizeof(set1[0]);
cout << lenghtOfLongestAP(set1, n1) << endl;
int set2[] = {1, 7, 10, 15, 27, 29};
int n2 = sizeof(set2)/sizeof(set2[0]);
cout << lenghtOfLongestAP(set2, n2) << endl;
int set3[] = {2, 4, 6, 8, 10};
int n3 = sizeof(set3)/sizeof(set3[0]);
cout << lenghtOfLongestAP(set3, n3) << endl;
return 0;
}
Java
// Java program to find Length of the
// Longest AP (llap) in a given sorted set.
// The code strictly implements the
// algorithm provided in the reference.
import java.io.*;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int lenghtOfLongestAP(int set[], int n)
{
if (n <= 2) return n;
// Create a table and initialize all
// values as 2. The value ofL[i][j] stores
// LLAP with set[i] and set[j] as first two
// elements of AP. Only valid entries are
// the entries where j>i
int L[][] = new int[n][n];
// Initialize the result
int llap = 2;
// Fill entries in last column as 2.
// There will always be two elements in
// AP with last number of set as second
// element in AP
for (int i = 0; i < n; i++)
L[i][n - 1] = 2;
// Consider every element as second element of AP
for (int j = n - 2; j >= 1; j--)
{
// Search for i and k for j
int i = j -1 , k = j + 1;
while (i >= 0 && k <= n - 1)
{
if (set[i] + set[k] < 2 * set[j])
k++;
// Before changing i, set L[i][j] as 2
else if (set[i] + set[k] > 2 * set[j])
{
L[i][j] = 2; i--;
}
else
{
// Found i and k for j, LLAP with i and j as first two
// elements is equal to LLAP with j and k as first two
// elements plus 1. L[j][k] must have been filled
// before as we run the loop from right side
L[i][j] = L[j][k] + 1;
// Update overall LLAP, if needed
llap = Math.max(llap, L[i][j]);
// Change i and k to fill
// more L[i][j] values for current j
i--; k++;
}
}
// If the loop was stopped due
// to k becoming more than
// n-1, set the remaining
// entties in column j as 2
while (i >= 0)
{
L[i][j] = 2;
i--;
}
}
return llap;
}
// Driver program
public static void main (String[] args)
{
int set1[] = {1, 7, 10, 13, 14, 19};
int n1 = set1.length;
System.out.println ( lenghtOfLongestAP(set1, n1));
int set2[] = {1, 7, 10, 15, 27, 29};
int n2 = set2.length;
System.out.println(lenghtOfLongestAP(set2, n2));
int set3[] = {2, 4, 6, 8, 10};
int n3 = set3.length;
System.out.println(lenghtOfLongestAP(set3, n3)) ;
}
}
// This code is contributed by vt_m
Python3
# Python 3 program to find Length of the
# Longest AP (llap) in a given sorted set.
# The code strictly implements the algorithm
# provided in the reference
# Returns length of the longest AP
# subset in a given set
def lenghtOfLongestAP(set, n):
if (n <= 2):
return n
# Create a table and initialize all
# values as 2. The value of L[i][j]
# stores LLAP with set[i] and set[j]
# as first two elements of AP. Only
# valid entries are the entries where j>i
L = [[0 for x in range(n)]
for y in range(n)]
llap = 2 # Initialize the result
# Fill entries in last column as 2.
# There will always be two elements
# in AP with last number of set as
# second element in AP
for i in range(n):
L[i][n - 1] = 2
# Consider every element as second
# element of AP
for j in range(n - 2, 0, -1):
# Search for i and k for j
i = j - 1
k = j + 1
while(i >= 0 and k <= n - 1):
if (set[i] + set[k] < 2 * set[j]):
k += 1
# Before changing i, set L[i][j] as 2
elif (set[i] + set[k] > 2 * set[j]):
L[i][j] = 2
i -= 1
else:
# Found i and k for j, LLAP with i and j
# as first two elements are equal to LLAP
# with j and k as first two elements plus 1.
# L[j][k] must have been filled before as
# we run the loop from right side
L[i][j] = L[j][k] + 1
# Update overall LLAP, if needed
llap = max(llap, L[i][j])
# Change i and k to fill more L[i][j]
# values for current j
i -= 1
k += 1
# If the loop was stopped due to k
# becoming more than n-1, set the
# remaining entties in column j as 2
while (i >= 0):
L[i][j] = 2
i -= 1
return llap
# Driver Code
if __name__ == "__main__":
set1 = [1, 7, 10, 13, 14, 19]
n1 = len(set1)
print(lenghtOfLongestAP(set1, n1))
set2 = [1, 7, 10, 15, 27, 29]
n2 = len(set2)
print(lenghtOfLongestAP(set2, n2))
set3 = [2, 4, 6, 8, 10]
n3 = len(set3)
print(lenghtOfLongestAP(set3, n3))
# This code is contributed by ita_c
C#
// C# program to find Length of the
// Longest AP (llap) in a given sorted set.
// The code strictly implements the
// algorithm provided in the reference.
using System;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int lenghtOfLongestAP(int []set,
int n)
{
if (n <= 2) return n;
// Create a table and initialize
// all values as 2. The value of
// L[i][j] stores LLAP with set[i]
// and set[j] as first two elements
// of AP. Only valid entries are
// the entries where j>i
int [,]L = new int[n, n];
// Initialize the result
int llap = 2;
// Fill entries in last column as 2.
// There will always be two elements
// in AP with last number of set as
// second element in AP
for (int i = 0; i < n; i++)
L[i, n - 1] = 2;
// Consider every element as
// second element of AP
for (int j = n - 2; j >= 1; j--)
{
// Search for i and k for j
int i = j - 1 , k = j + 1;
while (i >= 0 && k <= n - 1)
{
if (set[i] + set[k] < 2 * set[j])
k++;
// Before changing i, set L[i][j] as 2
else if (set[i] + set[k] > 2 * set[j])
{
L[i, j] = 2; i--;
}
else
{
// Found i and k for j, LLAP with
// i and j as first two elements
// is equal to LLAP with j and k
// as first two elements plus 1.
// L[j][k] must have been filled
// before as we run the loop from
// right side
L[i, j] = L[j, k] + 1;
// Update overall LLAP, if needed
llap = Math.Max(llap, L[i, j]);
// Change i and k to fill
// more L[i][j] values for current j
i--; k++;
}
}
// If the loop was stopped due
// to k becoming more than
// n-1, set the remaining
// entties in column j as 2
while (i >= 0)
{
L[i, j] = 2;
i--;
}
}
return llap;
}
// Driver Code
static public void Main ()
{
int []set1 = {1, 7, 10, 13, 14, 19};
int n1 = set1.Length;
Console.WriteLine(lenghtOfLongestAP(set1, n1));
int []set2 = {1, 7, 10, 15, 27, 29};
int n2 = set2.Length;
Console.WriteLine(lenghtOfLongestAP(set2, n2));
int []set3 = {2, 4, 6, 8, 10};
int n3 = set3.Length;
Console.WriteLine(lenghtOfLongestAP(set3, n3)) ;
}
}
// This code is contributed by Sach_Code
PHP
i
$L[$n][$n] = array(array());
$llap = 2; // Initialize the result
// Fill entries in last column as 2.
// There will always be two elements
// in AP with last number of set as
// second element in AP
for ($i = 0; $i < $n; $i++)
$L[$i][$n - 1] = 2;
// Consider every element as
// second element of AP
for ($j = $n - 2; $j >= 1; $j--)
{
// Search for i and k for j
$i = $j - 1;
$k = $j + 1;
while ($i >= 0 && $k <= $n - 1)
{
if ($set[$i] + $set[$k] < 2 * $set[$j])
$k++;
// Before changing i, set L[i][j] as 2
else if ($set[$i] + $set[$k] > 2 * $set[$j])
{
$L[$i][$j] = 2;
$i--; }
else
{
// Found i and k for j, LLAP with
// i and j as first two elements
// is equal to LLAP with j and k
// as first two elements plus 1.
// L[j][k] must have been filled
// before as we run the loop from
// right side
$L[$i][$j] = $L[$j][$k] + 1;
// Update overall LLAP, if needed
$llap = max($llap, $L[$i][$j]);
// Change i and k to fill more
// L[i][j] values for current j
$i--;
$k++;
}
}
// If the loop was stopped due to k
// becoming more than n-1, set the
// remaining entties in column j as 2
while ($i >= 0)
{
$L[$i][$j] = 2;
$i--;
}
}
return $llap;
}
// Driver Code
$set1 = array(1, 7, 10, 13, 14, 19);
$n1 = sizeof($set1);
echo lenghtOfLongestAP($set1, $n1),"\n";
$set2 = array(1, 7, 10, 15, 27, 29);
$n2 = sizeof($set2);
echo lenghtOfLongestAP($set2, $n2),"\n";
$set3 = array(2, 4, 6, 8, 10);
$n3 = sizeof($set3);
echo lenghtOfLongestAP($set3, $n3),"\n";
// This code is contributed by Sach_Code
?>
Javascript
输出:
4
3
5
时间复杂度: O(n 2 )
辅助空间: O(n 2 )
如何降低上述解决方案的空间复杂度?
我们还可以将空间复杂度降低到O(n) 。
以下是空间复杂度为O(n)的动态规划算法的实现。
C++
// C++ program to find Length of the
// Longest AP (llap) in a given sorted set.
#include
using namespace std;
// Returns length of the longest
// AP subset in a given set
int Solution(vector A)
{
int ans = 2;
int n = A.size();
if (n <= 2)
return n;
vector llap(n, 2);
sort(A.begin(), A.end());
for (int j = n - 2; j >= 0; j--)
{
int i = j - 1;
int k = j + 1;
while (i >= 0 && k < n)
{
if (A[i] + A[k] == 2 * A[j])
{
llap[j] = max(llap[k] + 1, llap[j]);
ans = max(ans, llap[j]);
i -= 1;
k += 1;
}
else if (A[i] + A[k] < 2 * A[j])
k += 1;
else
i -= 1;
}
}
return ans;
}
// Driver Code
int main()
{
vector a({ 9, 4, 7, 2, 10 });
cout << Solution(a) << endl;
return 0;
}
// This code is contributed by ashutosh450
Java
// Java program to find Length of the
// Longest AP (llap) in a given sorted set.
import java.util.*;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int Solution(int []A)
{
int ans = 2;
int n = A.length;
if (n <= 2)
return n;
int []llap = new int[n];
for(int i = 0; i < n; i++)
llap[i] = 2;
Arrays.sort(A);
for (int j = n - 2; j >= 0; j--)
{
int i = j - 1;
int k = j + 1;
while (i >= 0 && k < n)
{
if (A[i] + A[k] == 2 * A[j])
{
llap[j] = Math.max(llap[k] + 1, llap[j]);
ans = Math.max(ans, llap[j]);
i -= 1;
k += 1;
}
else if (A[i] + A[k] < 2 * A[j])
k += 1;
else
i -= 1;
}
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int []a = { 9, 4, 7, 2, 10 };
System.out.print(Solution(a) +"\n");
}
}
// This code is contributed by Rajput-Ji
Python
# Python program to find Length
# of the Longest AP (llap) in a given sorted set.
# Returns length of the longest AP subset in a given set
class Solution:
def Solve(self, A):
ans = 2
n= len(A)
if n<=2 :
return n
llap = [2]*n
A.sort()
for j in range(n-2, -1, -1):
i= j-1
k= j+1
while(i>=0 and k
C#
// C# program to find Length of the
// longest AP (llap) in a given sorted set.
using System;
class GFG
{
// Returns length of the longest
// AP subset in a given set
static int Solution(int []A)
{
int ans = 2;
int n = A.Length;
if (n <= 2)
return n;
int []llap = new int[n];
for(int i = 0; i < n; i++)
llap[i] = 2;
Array.Sort(A);
for (int j = n - 2; j >= 0; j--)
{
int i = j - 1;
int k = j + 1;
while (i >= 0 && k < n)
{
if (A[i] + A[k] == 2 * A[j])
{
llap[j] = Math.Max(llap[k] + 1, llap[j]);
ans = Math.Max(ans, llap[j]);
i -= 1;
k += 1;
}
else if (A[i] + A[k] < 2 * A[j])
k += 1;
else
i -= 1;
}
}
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int []a = { 9, 4, 7, 2, 10 };
Console.Write(Solution(a) +"\n");
}
}
// This code is contributed by Rajput-Ji
Javascript
输出:
3
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。