在这篇文章中,我们解释了如何使用动态编程有效地解决最长几何级数的问题。它涉及到使用地图数据结构来实现,这与其他标准问题不同。
目录
- 问题陈述。最长几何级数
- 天真方法
- 动态编程法
我们可以通过Naive Approch或动态编程来解决这个问题(我们必须使用Map of Float Map<Float, Integer>)。
问题陈述:最长的几何级数
什么是几何级数?
如果一个元素的序列遵循以下模式,它就是一个几何级数。
其中:
- a是几何级数的第一个元素
- 是几何级数的第1个元素。
在解决最长几何级数的问题之前,让我们先举个例子:
A = {2, 4, 8, 10, 50, 250}
所以,在这里我们发现了两个几何级数,一个是共同的比例2,另一个是5。
是的,每两个数字都会在几何级数中,所以我们要讨论的是超越这一点。
- : 2 4 8 , r=2
- : 2 10 50 250 , r=5
所以,我们的答案应该是4(a=2的大小)。
为了更好地理解这个问题,我们需要观察几何级数的一些特性。当且仅当三个数字持有属性时,它们可以是几何级数。
如果a、b、c都在几何级数中。
或者我们可以说。
天真的方法
在Naive方法中,我们将遵循以下步骤:
- 首先对数组进行排序。这将花费时间
- 通过一个循环,从第一个索引开始,然后再嵌套一个循环来选择下一个元素的进展
- 现在在最内层循环中,我们将检查所有具有相同公比的元素
时间复杂度:
动态编程方法
算法
动态编程的结构将是:
DP[i][j] = LGP with the first element
being array[i] and ratio being j
LGP = 最长的几何级数
如果有两个元素array[i]和array[j]的比率为R,并且与之前的元素对相比没有共同比率,那么:
DP[i][R] = 1
否则,如果前面的元素之间有共同的比率R,那么:
DP[i][r] = DP[j][r] + 1
答案是矩阵DP[][]中的最大值。
为了以最小的空间有效地实现这一技术,你需要使用一个Map数据结构。
使用动态编程找到最长的几何级数的步骤。
- 首先对所有元素进行排序,这样我们就可以很容易地跟踪具有相同公比的元素的数量。
- 初始化一个数组类型(map<double,int>),数组的长度是给定集合的大小。
- 使用两个循环,一个用于遍历我们的集合,另一个用于检查哪些元素与之前的元素有相同的公比。如果我们能找到相同的共同比率,那么就通过1来增加它,否则就为该地图创建一个具有共同比率的新实体,并以2来初始化它。
一步一步来
A = {5, 10, 20, 30}
所以数组的大小,
int n=A.size()
我们将声明一个地图类型的数组,用来存储具有共同比率(r)的进展的元素数量。
现在,我们认为如何使用动态编程来解决这个问题,我们必须为数组的每个索引维护一个map<float,integer>的列表。
让我们追踪所有数组的索引。
-
第一个索引的元素:5
在这个索引之前没有任何元素,所以继续 -
第二个索引的元素:10
在10之前,我们在第一个索引有一个元素,所以公比r=10/5。由于r=2,我们在第二个索引更新我们的地图list(2)(r)=2。
- 在第三个索引的元素:20
在这之前,我们在第一个和第二个索引有两个元素。一个是公共比率2,另一个是4。有了这个,我们更新数值如下:
list(3)(2) = list(2)(2) + 1 = 3
list(3)(4) = 2
- 第四个索引的元素:30
在这里我们得到了之前没有出现过的具有共同比率的元素:
list(4)(3/2) = 2
list(4)(3) = 2
list(4)(6) = 2
所以,在list(3)(2)=3处找到最大值:
答案=3
伪装代码
1: 将浮点数作为地图值,将整数作为关键值,声明
Map<Float,Integer>dp
2: 现在从第一个索引到最后一个索引进行迭代,然后将所有具有共同比率的值,放入地图中并递增
首先检查给定数组的大小让n成为数组的大小,如果(n<=2),那么简单的n就是我们的答案否则我们必须声明一个与数组大小相同的地图Map<Float,Integer>dp(n)
loop(i=0 to n)
{
loop (j=0 to less than i)
{
float r=A[i]/A[j]
Search r in dp[j]
if r is present in dp[j] then
dp[i][r] = dp[j][r] + 1 , because we found one more value which has
same common
ratio.
else
Create an map with defaul value 2
dp[i][r] =2 ,
}
}
现在我们来讨论一下它的各种时间和空间的复杂性...
复杂度
- 最坏情况下的时间复杂度:
Θ(n^2) - 平均情况下的时间复杂度:
Θ(n^2) - 最佳情况下的时间复杂度:
Θ(n^2) - 空间复杂度:
Θ(n^2)
困境:
int findLargestSequence(int A[])
{
int n=sizeof(A)/sizeof(A[0]);
if(n<=2)
return n;
sort(A,A+n); //first sort all the elements
map<float,int>dp[n]; // declare a dp array of size n.
int max=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
float r=A[i]/A[j];
if(dp[j].find(r)!=dp[j].end());
{
dp[i].insert(make_pair(r,2));
//sequence has at least two elements with a ratio(r)
}
else
{
dp[i][r]=dp[j][r]+1;
// if at the jth index we already have a sequence with common ratio r
}
if(dp[i][r]>max)
max=dp[i][r];
}
}
return max;
}
时间和空间复杂度
时间复杂度:
空间复杂度:
关键点
我们必须对浮动值进行映射,因为公共比率可以是浮动值,也可以是小数,两者都不是。
通过OpenGenus的这篇文章,你一定对最长几何级数有了完整的了解。