📜  最长的算术级数| DP-35

📅  最后修改于: 2021-05-07 00:53:22             🧑  作者: Mango

给定一组数字,找出将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个或更多元素,则答案为true,否则为false。
要找到这三个元素,我们首先将一个元素固定为中间元素,然后搜索其他两个元素(一个较小而另一个较大)。我们从第二个元素开始,并将每个元素固定为中间元素。为了使元素set [j]位于AP的中间,必须存在元素’set [i]’和’set [k]’,使得set [i] + set [k] = 2 * set [j]其中0 <= i 如何有效地找到给定j的i和k?我们可以使用以下简单算法在线性时间内找到i和k。

  1. 将i初始化为j-1并将k初始化为j + 1
  2. 当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(do 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;
}


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 ongestrithmetic 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

的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
?>

Java脚本


输出:

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

Java脚本


输出:

3