问题陈述为:
给你一个数组,你需要找到索引(i,j,k(的三元组的数量,使得这些索引处的元素对于给定的公比r和i<j<k.例如,arr=[1,4,16,64]。如果r=4,则在指数(0,1,2(和(1,2,3(处有[1,4,16]和[4,16,64]。
我有一个解决方案,但我无法理解。有人能帮我吗?
def countTriplets(arr, r):
count = 0
dict = {}
dictPairs = {}
for i in reversed(arr):
if i*r in dictPairs:
count += dictPairs[i*r]
if i*r in dict:
dictPairs[i] = dictPairs.get(i, 0) + dict[i*r]
dict[i] = dict.get(i, 0) + 1
return count
这个问题的工作方式是使用"dict";以保持数组中每个数字的连续计数。然后,它使用";dictPairs";以保持i和(i*r(的对的连续计数。最后,如果(i*r(存在于dictPairs中,那就意味着存在一个三元组,因为如果(i**r(存在于dictPairs,那就必须意味着(i*r*r(在dict中存在,并且计数增加了dictPairs对的实例数。
使用提供的示例并逐步迭代可能会给出更清晰的答案:
反向阵列中的第一个元素是64
- 256(64*4(不在dictPairs中,也不在dict中
- 将对(64,1(添加到dict,因为它还不在dict中,因此从dict.get(i,0(返回默认值0
阵列中的第二个元素是16
- 64(16*4(不在dictPairs中,但在dict中。因此,(16,1(被添加到dictPairs,因为dictPairs还不包含16,dict[64]等于1
- 将对(16,1(添加到dict
阵列中的第三个元素是4
- 16(4*4(在dictPairs中!这意味着计数增加1,因为dictPairs[16]等于1
- 16也在dict中,因此将对(16,1(添加到dictPairs
- 将对(4,1(添加到dict
数组中的最后一个元素是1
- 4在dictPairs中,因此计数再次增加1,因为dictPairs[4]等于1
- 4也在dict中,因此将对(4,1(添加到dictPairs中
- 将对(1,1(添加到dict
因为有两个三元组,所以计数为2。
上面的程序利用这两个字典来跟踪可能的三元组;
现在,从最后开始(因为我们有一个给定的约束i<j<k(
dict跟踪元素i,dictPairs跟踪元素i*r。
现在,我们检查以下内容;
- 如果dictPairs中存在元素i*r,如果存在,则存在三元组(i,i*r、i*r*r(
- 如果dict中存在元素i*r,如果存在,则存在一对(i,i*r(
- 如果它们都不存在,我们将其添加到dict中,使其成为未来三元组的候选者
始终建议跟踪算法以更好地了解其工作原理,
假设我们有一个数组[1,2,8,3,4,6,12],并且给定的公共比为2。
现在,从最后开始,
最初;
dict = {}
dictPairs = {}
元素12==>检查dict或dictPairs中是否存在12*2==>两者都不存在===>将其添加到dict
dict = {12 : 1} dictPairs = {}
元素6==>检查dict或dictPairs中是否存在6*2==>存在于dict===>将其添加到dictPairs
dict = {12 : 1} dictPairs = {6 : 1}
元素4==>检查dict或dictPairs中是否存在4*2==>两者都不存在===>将其添加到dict
dict = {12 : 1, 4 : 1} dictPairs = {6 : 1}
元素3==>检查dict或dictPairs中是否存在3*2==>存在于dictPairs中==>增量计数
dict = {12 : 1, 4 : 1} dictPairs = {6 : 1}
元素8==>检查dict或dictPairs中是否存在8*2==>两者都不存在===>将其添加到dict
dict = {12 : 1, 4 : 1, 8 : 1} dictPairs = {6 : 1}
元素2==>检查dict或dictPairs中是否存在2*2==>存在于dict===>将其添加到dictPairs
dict = {12 : 1, 4 : 1, 8 : 1} dictPairs = {6 : 1, 2 : 1}
元素1==>检查dict或dictPairs中是否存在1*2==>存在于dictPairs中==>增量计数
dict = {12 : 1, 4 : 1, 8 : 1} dictPairs = {6 : 1, 2 : 1}
您可以看到三元组(2、4、8(是如何不按顺序选择的。
需要注意的一件事是巧妙地使用dict.get((函数来添加新的条目