力扣每日一题+python知识点回顾(二)

力扣题目:同积元组(题号:1726)

给你一个由不同正整数组成的数组nums,请你返回满足a * b = c * d的元组(a, b, c, d)的数量。其中abcd都是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
posted @ 2023-10-19 20:48  风雪无常  阅读(24)  评论(0编辑  收藏  举报