力扣题目:同积元组(题号:1726)
给你一个由不同正整数组成的数组nums,请你返回满足a * b = c * d的元组(a, b, c, d)的数量。其中a、b、c和d都是nums中的元素,且a != b != c != d。
示例1:
输入:nums = [2,3,4,6]
输出:8
解释:存在 8 个满足题意的元组:
(2,6,3,4) , (2,6,4,3) , (6,2,3,4) , (6,2,4,3)
(3,4,2,6) , (4,3,2,6) , (3,4,6,2) , (4,3,6,2)
示例 2:
输入:nums = [1,2,4,5,10]
输出:16
解释:存在 16 个满足题意的元组:
(1,10,2,5) , (1,10,5,2) , (10,1,2,5) , (10,1,5,2)
(2,5,1,10) , (2,5,10,1) , (5,2,1,10) , (5,2,10,1)
(2,10,4,5) , (2,10,5,4) , (10,2,4,5) , (10,2,5,4)
(4,5,2,10) , (4,5,10,2) , (5,4,2,10) , (5,4,10,2)
提示:nums中的所有元素互不相同
编程思路:哈希表
首先,从nums计算任意两个元素的乘积,并将其存储在哈希表count中,哈希表用字典dict来保存,key代表乘积值,value代表乘积值的计数,
每计数一个,代表存在一个乘积为key的乘积。因此答案为对每个乘积的计算组合数以确定满足条件的元组数量,而每个元组有8种排列方式,最终的的结果还得成语8。
代码首先使用conbinations函数来计算任意两个元素的乘积,下面进行对conbinations函数回顾:
conbinations函数:
conbinations函数源自itertools库中的函数,是内置库直接import即可
conbinations(iterable, num)函数是根据特定的元素和长度,生成一系列组合的元素。
参数:
iterable -- 是一个list参数,存放特定元素
num -- 是int,指从特定元素中取出num个元素生成组合元素。
实例1:从固定元素中取出特定长度的组合元素
从1、2、3、4、5五个元素中取两个元素进行组合,得到所有组合,并打印出来。
import itertools
num = [ 1, 2, 3, 4, 5]
for element in itertools.combinations(num, 2):
print(element)
得到结果:
(1, 1)
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
(4, 5)
可以发现生成的组合元素是位置的组合,即第一个位置的元素和后面所有的元素组合。
第二个位置的元素和位置大于2的所有元素组合,依次类推。
实例2:生成组合入模特征
为了对不同入模特征模型效果进行衡量,可以写循环输入不同的组合特征,得到对应模型效果。
此时,需要生成不同的特征组合,可以应用combination函数。
#遍历所有特征
features = ['feature_1', 'feature_2', 'feature_3', 'feature_4']
#选择入模特征
for i in range(len(features)):
comb = itertools.combinations(features, i+1)
for i in comb:
print(i)
得到结果:
('feature_1',)
('feature_2',)
('feature_3',)
('feature_4',)
('feature_1', 'feature_2')
('feature_1', 'feature_3')
('feature_1', 'feature_4')
('feature_2', 'feature_3')
('feature_2', 'feature_4')
('feature_3', 'feature_4')
('feature_1', 'feature_2', 'feature_3')
('feature_1', 'feature_2', 'feature_4')
('feature_1', 'feature_3', 'feature_4')
('feature_2', 'feature_3', 'feature_4')
('feature_1', 'feature_2', 'feature_3', 'feature_4')
也可以调整num函数,让入模变量至少有2个,感兴趣的可以自行尝试。
defaultdict(list)函数
通常 Python 中字典(dict)这种数据类型是通过键值对来存取的,当索引一个不存在的键时,就会引发 keyerror 异常。那么,defaultdict 就可以解决这个问题,它可以实现为不存的键值返回一个默认值。
defaultdict()函数源自collections模块,在初始化时可以提供一个default-factory的参数,default-factory接收一个工厂函数作为参数, 可以是int、str、list 等内置函数,也可以是自定义函数,进而构建成一个有默认值的字典。
如defaultdict(list),会构建一个默认value为list的字典。
示例1: 统计字符串中字母出现的个数。
from collections import defaultdict
s = 'mississippi'
d = defaultdict(int)
for k in s:
d[k] += 1
print(d)
输出
defaultdict(<class 'list'>, {'m': 1, 'i': 4, 's': 4, 'p': 2})
示例2:
from collections import defaultdict
result = defaultdict(list)
data = [("p", 1), ("p", 2), ("p", 3),
("h", 1), ("h", 2), ("h", 3)]
for (key, value) in data:
result[key].append(value)
print(result)
输出:
defaultdict(<class 'list'>, {'p': [1, 2, 3], 'h': [1, 2, 3]})
算法思路
有了以上回顾,我们先用combinations列出每个存在的组合,计算其乘积,对每个乘积进行计数。然后,对每个乘积的计数使用组合n*(n-1)/2来计算存在的元组。最后,对每个组合有八种排列方法,因此结果需要乘以8。
注意:
1.不考虑不同乘积中存在同样元素的问题,因为在二元乘法中,相同元素要获得同一乘积只有乘以同一数字。
2.python中使用//来表示整除,以避免计数为1的乘积。
编程代码:
解题代码:
class Solution:
def tupleSameProduct(self, nums: List[int]) -> int:
count = defaultdict(int)
ans = 0
#求出每个任意两个数的乘积,用字典存储,键为乘积值,值为计数
for m, n in combinations(nums, 2):
product = m * n
count[product] += 1
#从哈希表同个乘积中的值,计算存在多少对相同的乘积,用组合n*(n-1)/2来计算,整除用//。
#注:不用考虑不同乘积中存在同样元素的问题,因为在二元乘法中,相同元素要获得同一乘积需要乘以同一数字
for p in count.values():
ans += p * (p - 1) // 2 #//表示整除
#一个组合有八种排列方法,结果乘8
return ans * 8
标签:defaultdict,知识点,乘积,组合,10,python,元素,feature,力扣
From: https://www.cnblogs.com/LWHD/p/17775621.html