2176.统计数组中相等且可以被整除的数对
问题分析
理解问题:
给定一个整数数组 nums 和一个整数 k。
需要找到所有满足 0 <= i < j < n 且 nums[i] == nums[j] 且 (i * j) 能被 k 整除的数对 (i, j) 的数目
思路
算法思路:
遍历数组中的每一对元素 (i, j)(其中 i < j)。
检查 nums[i] 是否等于 nums[j]。
如果相等,再检查 i * j 是否能被 k 整除。
如果上述条件都满足,则计数器加一。
代码
class Solution:
def countPairs(self, nums: List[int], k: int) -> int:
ans = 0
for i in range(len(nums)-1):
for j in range(i + 1, len(nums)):
if nums[i] == nums[j] and (i * j) % k == 0:
ans += 1
return ans
复杂度分析
时间复杂度:两个for循环: ( O(n^2) )。
空间复杂度:( O(1) )
学习
优化方法:枚举右维护左
如果数组长度n = 10^5 ,暴力枚举超时
问题简化:
代码:
# 预处理每个数的因子
MX = 101
divisors = [[] for _ in range(MX)]
for i in range(1, MX):
for j in range(i, MX, i):
divisors[j].append(i)
class Solution:
def countPairs(self, nums: list[int], k: int) -> int:
ans = 0
cnt = defaultdict(int)
for j, x in enumerate(nums): # 枚举 j,计算左边有多少个符合要求的 i
if j and x == nums[0]:
ans += 1 # 单独统计 i=0 的情况
k2 = k // gcd(k, j) # i 必须是 k2 的倍数
ans += cnt[(x, k2)]
for d in divisors[j]: # j 是 d 的倍数
cnt[(x, d)] += 1
return ans
复杂度分析
方法学习:
作者:灵茶山艾府
链接:https://leetcode.cn/problems/count-equal-and-divisible-pairs-in-an-array/solutions/1277713/mo-ni-by-endlesscheng-wegn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。