# Longest Geometric Progression

• Difficulty Level : Hard
• Last Updated : 03 Mar, 2022

Given a set of numbers, find the Length of the Longest Geometrix Progression (LLGP) in it. The common ratio of GP must be an integer.
Examples:

```set[] = {5, 7, 10, 15, 20, 29}
output = 3
The longest geometric progression is {5, 10, 20}

set[] = {3, 9, 27, 81}
output = 4```

This problem is similar to Longest Arithmetic Progression Problem. We can solve this problem using Dynamic Programming.
We first sort the given set. We use an auxiliary table L[n][n] to store results of subproblems. An entry L[i][j] in this table stores LLGP with set[i] and set[j] as first two elements of GP and j > i. The table is filled from bottom right to top left. To fill the table, j (second element in GP) is first fixed. i and k are searched for a fixed j. If i and k are found such that i, j, k form an GP, then the value of L[i][j] is set as L[j][k] + 1. Note that the value of L[j][k] must have been filled before as the loop traverses from right to left columns.
Following is the implementation of the Dynamic Programming algorithm.

## C++

 `// C++ program to find length``// of the longest geometric``// progression in a given set``#include ``#include ``using` `namespace` `std;` `// Returns length of the``// longest GP subset of set[]``int` `lenOfLongestGP(``int` `set[], ``int` `n)``{``    ``// Base cases``    ``if` `(n < 2)``        ``return` `n;``    ``if` `(n == 2)``        ``return` `(set % set == 0) ? 2 : 1;` `    ``// Let us sort the set first``    ``sort(set, set+n);` `    ``// An entry L[i][j] in this``    ``// table stores LLGP with``    ``// set[i] and set[j] as first``    ``// two elements of GP``    ``// and j > i.``    ``int` `L[n][n];` `    ``// Initialize result (A single element``    ``// is always a GP)``    ``int` `llgp = 1;` `    ``// Initialize values of last column``    ``for` `(``int` `i = 0; i < n - 1; ++i) {``        ``if` `(set[n-1] % set[i] == 0)``        ``{``            ``L[i][n-1] = 2;``            ``if` `(2 > llgp)``              ``llgp = 2;``        ``}``        ``else``        ``{``            ``L[i][n-1] = 1;``        ``}``    ``}``    ``L[n-1][n-1] = 1;`  `    ``// Consider every element as``    ``// second element of GP``    ``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)``        ``{``            ` `            ``// Two cases when i, j and k don't form``            ``// a GP.``            ``if` `(set[i] * set[k] < set[j]*set[j])``            ``{``                ``++k;``            ``}``            ``else` `if` `(set[i] * set[k] > set[j]*set[j])``            ``{``                ``if` `(set[j] % set[i] == 0)``                ``{``                    ``L[i][j] = 2;``                ``}``                ``else``                ``{``                    ``L[i][j] = 1;``                ``}``                ``--i;``            ``}`  `            ``// i, j and k form GP, LLGP with i and j as``            ``// first two elements is equal to LLGP 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``            ``else``            ``{``                ``if` `(set[j] % set[i] == 0)``                ``{``                    ``L[i][j] = L[j][k] + 1;` `                    ``// Update overall LLGP``                    ``if` `(L[i][j] > llgp)``                        ``llgp = L[i][j];``                ``} ``else` `{``                  ``L[i][j] = 1;``                ``}`  `                ``// 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 entries``        ``// in column j as 1 or 2 based on divisibility``        ``// of set[j] by set[i]``        ``while` `(i >= 0)``        ``{``            ``if` `(set[j] % set[i] == 0)``            ``{``                ``L[i][j] = 2;``                ``if` `(2 > llgp)``                    ``llgp = 2;``            ``}``            ``else``                ``L[i][j] = 1;``            ``--i;``        ``}``    ``}` `    ``// Return result``    ``return` `llgp;``}` `// Driver code``int` `main()``{``    ``int` `set1[] = {1, 3, 9, 27, 81, 243};``    ``int` `n1 = ``sizeof``(set1)/``sizeof``(set1);``    ``cout << lenOfLongestGP(set1, n1) << ``"\n"``;` `    ``int` `set2[] = {1, 3, 4, 9, 7, 27};``    ``int` `n2 = ``sizeof``(set2)/``sizeof``(set2);``    ``cout << lenOfLongestGP(set2, n2) << ``"\n"``;` `    ``int` `set3[] = {2, 3, 5, 7, 11, 13};``    ``int` `n3 = ``sizeof``(set3)/``sizeof``(set3);``    ``cout << lenOfLongestGP(set3, n3) << ``"\n"``;` `    ``return` `0;``}`

## Java

 `// Java program to find length``// of the longest geometric``// progression in a given set``import` `java.util.*;` `class` `GFG {` `    ``// Returns length of the longest GP subset of set[]``    ``static` `int` `lenOfLongestGP(``int` `set[], ``int` `n)``    ``{``        ``// Base cases``        ``if` `(n < ``2``) {``            ``return` `n;``        ``}``        ``if` `(n == ``2``) {``            ``return` `(set[``1``] % set[``0``] == ``0` `? ``2` `: ``1``);``        ``}` `        ``// Let us sort the set first``        ``Arrays.sort(set);` `        ``// An entry L[i][j] in this table``        ``// stores LLGP with set[i] and set[j]``        ``// as first two elements of GP``        ``// and j > i.``        ``int` `L[][] = ``new` `int``[n][n];` `        ``// Initialize result (A single``        ``// element is always a GP)``        ``int` `llgp = ``1``;` `        ``// Initialize values of last column``        ``for` `(``int` `i = ``0``; i < n - ``1``; ++i) {``            ``if` `(set[n - ``1``] % set[i] == ``0``) {``                ``L[i][n - ``1``] = ``2``;``                ``if` `(``2` `> llgp)``                    ``llgp = ``2``;``            ``}``            ``else` `{``                ``L[i][n - ``1``] = ``1``;``            ``}``        ``}``        ``L[n - ``1``][n - ``1``] = ``1``;` `        ``// Consider every element as second element of GP``        ``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``) {``                ``// Two cases when i, j and k``                ``// don't form a GP.``                ``if` `(set[i] * set[k] < set[j] * set[j]) {``                    ``++k;``                ``}``                ``else` `if` `(set[i] * set[k]``                         ``> set[j] * set[j]) {``                    ``if` `(set[j] % set[i] == ``0``) {``                        ``L[i][j] = ``2``;``                        ``if` `(``2` `> llgp)``                            ``llgp = ``2``;``                    ``}``                    ``else` `{``                        ``L[i][j] = ``1``;``                    ``}``                    ``--i;``                ``}` `                ``// i, j and k form GP, LLGP with i and j as``                ``// first two elements is equal to LLGP 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``                ``else` `{``                    ``if` `(set[j] % set[i] == ``0``) {``                        ``L[i][j] = L[j][k] + ``1``;` `                        ``// Update overall LLGP``                        ``if` `(L[i][j] > llgp) {``                            ``llgp = L[i][j];``                        ``}``                    ``}``                    ``else` `{``                        ``L[i][j] = ``1``;``                    ``}` `                    ``// 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 entries``            ``// in column j as 1 or 2 based on divisibility``            ``// of set[j] by set[i]``            ``while` `(i >= ``0``) {``                ``if` `(set[j] % set[i] == ``0``) {``                    ``L[i][j] = ``2``;``                    ``if` `(``2` `> llgp)``                        ``llgp = ``2``;``                ``}``                ``else` `{``                    ``L[i][j] = ``1``;``                ``}``                ``--i;``            ``}``        ``}` `        ``// Return result``        ``return` `llgp;``    ``}` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `set1[] = { ``1``, ``3``, ``9``, ``27``, ``81``, ``243` `};``        ``int` `n1 = set1.length;``        ``System.out.print(lenOfLongestGP(set1, n1) + ``"\n"``);` `        ``int` `set2[] = { ``1``, ``3``, ``4``, ``9``, ``7``, ``27` `};``        ``int` `n2 = set2.length;``        ``System.out.print(lenOfLongestGP(set2, n2) + ``"\n"``);` `        ``int` `set3[] = { ``2``, ``3``, ``5``, ``7``, ``11``, ``13` `};``        ``int` `n3 = set3.length;``        ``System.out.print(lenOfLongestGP(set3, n3) + ``"\n"``);``    ``}``}` `/* This code contributed by PrinciRaj1992 */`

## Python3

 `# Python3 program to find length``# of the longest geometric``# progression in a given sett` `# Returns length of the longest GP``# subset of sett[]` `def` `lenOfLongestGP(sett, n):``    ``# Base cases``    ``if` `n < ``2``:``        ``return` `n``    ``if` `n ``=``=` `2``:``        ``return` `2` `if` `(sett[``1``] ``%` `sett[``0``] ``=``=` `0``) ``else` `1``    ``# let us sort the sett first``    ``sett.sort()` `    ``# An entry L[i][j] in this``    ``# table stores LLGP with``    ``# sett[i] and sett[j] as first``    ``# two elements of GP``    ``# and j > i.``    ``L ``=` `[[``0` `for` `i ``in` `range``(n)] ``for` `i ``in` `range``(n)]` `    ``# Initialize result (A single``    ``# element is always a GP)``    ``llgp ``=` `1` `    ``# Initialize values of last column``    ``for` `i ``in` `range``(``0``, n``-``1``):``        ``if` `sett[n``-``1``] ``%` `sett[i] ``=``=` `0``:``            ``L[i][n``-``1``] ``=` `2``            ``if` `2` `> llgp:``                ``llgp ``=` `2``        ``else``:``            ``L[i][n``-``1``] ``=` `1``    ``L[n``-``1``][n``-``1``] ``=` `1` `    ``# Consider every element as second element of GP``    ``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``:` `            ``# Two cases when i, j and k don't form``            ``# a GP.``            ``if` `sett[i] ``*` `sett[k] < sett[j] ``*` `sett[j]:``                ``k ``+``=` `1``            ``else` `if` `sett[i] ``*` `sett[k] > sett[j] ``*` `sett[j]:``                ``if` `sett[j] ``%` `sett[i] ``=``=` `0``:``                    ``L[i][j] ``=` `2``                ``else``:``                    ``L[i][j] ``=` `1``                ``i ``-``=` `1` `            ``# i, j and k form GP, LLGP with i and j as``            ``# first two elements is equal to LLGP 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``            ``else``:``                ``if` `sett[j] ``%` `sett[i] ``=``=` `0``:``                    ``L[i][j] ``=` `L[j][k] ``+` `1` `                    ``# Update overall LLGP``                    ``if` `L[i][j] > llgp:``                        ``llgp ``=` `L[i][j]``                ``else``:``                    ``L[i][j] ``=` `1` `                ``# 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 entries``        ``# in column j as 1 or 2 based on divisibility``        ``# of sett[j] by sett[i]``        ``while` `i >``=` `0``:``            ``if` `sett[j] ``%` `sett[i] ``=``=` `0``:``                ``L[i][j] ``=` `2``            ``else``:``                ``L[i][j] ``=` `1``            ``i ``-``=` `1` `    ``return` `llgp`  `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``set1 ``=` `[``1``, ``3``, ``9``, ``27``, ``81``, ``243``]``    ``n1 ``=` `len``(set1)``    ``print``(lenOfLongestGP(set1, n1))` `    ``set2 ``=` `[``1``, ``3``, ``4``, ``9``, ``7``, ``27``]``    ``n2 ``=` `len``(set2)``    ``print``(lenOfLongestGP(set2, n2))` `    ``set3 ``=` `[``2``, ``3``, ``5``, ``7``, ``11``, ``13``]``    ``n3 ``=` `len``(set3)``    ``print``(lenOfLongestGP(set3, n3))` `# this code is contributed by sahilshelangia`

## C#

 `// C# program to find length``// of the longest geometric``// progression in a given Set``using` `System;` `class` `GFG``{` `    ``// Returns length of the``    ``// longest GP subset of Set[]``    ``static` `int` `lenOfLongestGP(``int` `[]Set, ``int` `n)``    ``{``        ``// Base cases``        ``if` `(n < 2)``        ``{``            ``return` `n;``        ``}``        ``if` `(n == 2)``        ``{``            ``return` `(Set % Set == 0 ? 2 : 1);``        ``}` `        ``// Let us sort the Set first``        ``Array.Sort(Set);` `        ``// An entry L[i,j] in this table``        ``// stores LLGP with Set[i] and Set[j]``        ``// as first two elements of GP``        ``// and j > i.``        ``int` `[,]L = ``new` `int``[n, n];` `        ``// Initialize result (A single``        ``// element is always a GP)``        ``int` `llgp = 1;` `        ``// Initialize values of last column``        ``for` `(``int` `i = 0; i < n - 1; ++i)``        ``{``            ``if` `(Set[n - 1] % Set[i] == 0)``            ``{``                ``L[i, n - 1] = 2;``                ``if` `(2 > llgp)``                    ``llgp  = 2;``            ``}``            ``else``            ``{``                ``L[i, n - 1] = 1;``            ``}``        ``}``        ``L[n - 1, n - 1] = 1;` `        ``// Consider every element``        ``// as second element of GP``        ``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)``            ``{``                ``// Two cases when i, j and k``                ``// don't form a GP.``                ``if` `(Set[i] * Set[k] < Set[j] * Set[j])``                ``{``                    ``++k;``                ``}``                ``else` `if` `(Set[i] * Set[k] > Set[j] * Set[j])``                ``{``                    ``if` `(Set[j] % Set[i] == 0)``                    ``{``                        ``L[i,j] = 2;``                        ``if` `(2 > llgp)``                            ``llgp = 2;``                    ``}``                    ``else``                    ``{``                        ``L[i,j] = 1;``                    ``}``                    ``--i;``                ``}``                ` `                ``// i, j and k form GP, LLGP with i and j as``                ``// first two elements is equal to LLGP 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``                ``else``                ``{``                    ``if` `(Set[j] % Set[i] == 0)``                    ``{``                        ``L[i, j] = L[j, k] + 1;` `                        ``// Update overall LLGP``                        ``if` `(L[i, j] > llgp)``                        ``{``                            ``llgp = L[i, j];``                        ``}``                    ``}``                    ``else``                    ``{``                        ``L[i, j] = 1;``                    ``}` `                    ``// 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 entries``            ``// in column j as 1 or 2 based on divisibility``            ``// of Set[j] by Set[i]``            ``while` `(i >= 0)``            ``{``                ``if` `(Set[j] % Set[i] == 0)``                ``{``                    ``L[i, j] = 2;``                    ``if` `(2 > llgp)``                        ``llgp = 2;``                ``}``                ``else``                ``{``                    ``L[i, j] = 1;``                ``}``                ``--i;``            ``}``        ``}` `        ``// Return result``        ``return` `llgp;``    ``}` `    ``// Driver code``    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int` `[]set1 = {1, 3, 9, 27, 81, 243};``        ``int` `n1 = set1.Length;``        ``Console.Write(lenOfLongestGP(set1, n1) + ``"\n"``);` `        ``int` `[]set2 = {1, 3, 4, 9, 7, 27};``        ``int` `n2 = set2.Length;``        ``Console.Write(lenOfLongestGP(set2, n2) + ``"\n"``);` `        ``int` `[]set3 = {2, 3, 5, 7, 11, 13};``        ``int` `n3 = set3.Length;``        ``Console.Write(lenOfLongestGP(set3, n3) + ``"\n"``);``    ``}``}` `// This code has been contributed by 29AjayKumar`

## Javascript

 ``

Output:

```6
4
1```

Time Complexity: O(n2
Auxiliary Space: O(n2)
This article is contributed by Vivek Pandya. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.