1。问题
函数有两个参数,分别是:
所以,输入可以是这样的
arr: [1, 2, 2, 4]
r: 2
目标是返回形成几何级数的三元组的计数。
2。如何解决它
要解决它有多种方法。例如,从SagunB 基于comment from RobertsN
- 可以在 O(n) 中完成 -> 单次通过数据
- 不需要除法,只需要乘以 R 即可
- 必须使用 map(C++) 或 dict(Java, Python) -> 可以是无序映射(节省 O(logN))
- 在读取值时尝试向前思考 -> 该值以后会形成三元组的一部分吗?
- 无需将 (R == 1) 视为极端情况
from collections import Counter
# Complete the countTriplets function below.
def countTriplets(arr, r):
r2 = Counter()
r3 = Counter()
count = 0
for v in arr:
if v in r3:
count += r3[v]
if v in r2:
r3[v*r] += r2[v]
r2[v*r] += 1
return count
或者像你说的
from collections import defaultdict
# Complete the countTriplets function below.
def countTriplets(arr, r):
v2 = defaultdict(int)
v3 = defaultdict(int)
count = 0
for k in arr:
count += v3[k]
v3[k*r] += v2[k]
v2[k*r] += 1
return count
3。最终结果
两个案例都将通过HackerRank中当前的所有13个测试案例
4。你的情况说明
来自 RobertsN 的评论几乎解释了您的代码(与您的代码非常相似)。尽管如此,为了更好地了解代码的工作原理,只需打印计数发生的情况,v2 和 v3。
假设你有输入
4 2
1 2 2 4
预期的输出是
2
另外,我们知道 definition 的 v2 和 v3 看起来都像
defaultdict(<class 'int'>, {})
这让 for 循环留待理解。运算符 += 可能会引起一些混乱,但那是 already addressed by me in another answer。
所以,现在要了解其余部分,我们可以将循环更改为
for k in arr:
print(f"Looping...")
print(f"k: {k}")
print(f"v3_before_count: {v3}")
count += v3[k]
print(f"count: {count}")
print(f"k*r: {k*r}")
print(f"v3_before: {v3}")
v3[k*r] += v2[k]
print(f"v3[k*r]: {v3[k*r]}")
print(f"v2[k]: {v2[k]}")
print(f"v3_after: {v3}")
print(f"v2_before: {v2}")
v2[k*r] += 1
print(f"v2_after: {v2}")
print(f"v2[k*r]: {v2[k*r]}")
会让你看到
Looping...
k: 1
v3_before_count: defaultdict(<class 'int'>, {})
count: 0
k*r: 2
v3_before: defaultdict(<class 'int'>, {1: 0})
v2_before_v3: defaultdict(<class 'int'>, {1: 0})
v3[k*r]: 0
v2[k]: 0
v3_after: defaultdict(<class 'int'>, {1: 0, 2: 0})
v2_before: defaultdict(<class 'int'>, {1: 0})
v2_after: defaultdict(<class 'int'>, {1: 0, 2: 1})
v2[k*r]: 1
Looping...
k: 2
v3_before_count: defaultdict(<class 'int'>, {1: 0, 2: 0})
count: 0
k*r: 4
v3_before: defaultdict(<class 'int'>, {1: 0, 2: 0})
v2_before_v3: defaultdict(<class 'int'>, {1: 0, 2: 0})
v3[k*r]: 1
v2[k]: 1
v3_after: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 1})
v2_before: defaultdict(<class 'int'>, {1: 0, 2: 1})
v2_after: defaultdict(<class 'int'>, {1: 0, 2: 1, 4: 1})
v2[k*r]: 1
Looping...
k: 2
v3_before_count: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 1})
count: 0
k*r: 4
v3_before: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 1})
v2_before_v3: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 1})
v3[k*r]: 2
v2[k]: 1
v3_after: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 2})
v2_before: defaultdict(<class 'int'>, {1: 0, 2: 1, 4: 1})
v2_after: defaultdict(<class 'int'>, {1: 0, 2: 1, 4: 2})
v2[k*r]: 2
Looping...
k: 4
v3_before_count: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 2})
count: 2
k*r: 8
v3_before: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 2})
v2_before_v3: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 2})
v3[k*r]: 2
v2[k]: 2
v3_after: defaultdict(<class 'int'>, {1: 0, 2: 0, 4: 2, 8: 2})
v2_before: defaultdict(<class 'int'>, {1: 0, 2: 1, 4: 2})
v2_after: defaultdict(<class 'int'>, {1: 0, 2: 1, 4: 2, 8: 1})
v2[k*r]: 1
并提取所需的错误。我们可以从中观察到什么?
- 最后一个循环中的计数从 0 增加到 2。
- k 遍历 arr 的所有值 - 因此它将是 1、2、2 和 4。
- 在初始循环中,v3_before_count 为 {},v3_before 为 {1:0}
- 等
这个过程很可能会产生问题,回答这些问题会让你更深入地理解它。