难度: Medium
Submission
运行时间: 89 ms
内存: 21.1 MB
class Solution: def minProductSum(self, nums1: List[int], nums2: List[int]) -> int: # nums1.sort() # index = sorted(range(len(nums1)), key = lambda x: nums2[x], reverse = True) # return sum(x * nums2[y] for x, y in zip(nums1, index)) num1 = [0] * 100 num2 = [0] * 100 for n1, n2 in zip(nums1, nums2): num1[n1-1] += 1 num2[n2-1] += 1 ans = 0 L, R = 0, 99 while R >= 0: cnt = min(num1[L], num2[R]) ans += cnt * (L+1) * (R+1) num1[L] -= cnt num2[R] -= cnt while L < 100 and num1[L] == 0: L += 1 while R >= 0 and num2[R] == 0: R -= 1 return ans
Explain
题解的核心思想是利用计数排序的方式来避免对原始数组进行排序,从而在一定程度上优化时间复杂度。具体而言,题解创建了两个长度为100的数组num1和num2,用来计数nums1和nums2中各个元素的出现次数(假设元素大小在1到100之间)。然后,使用双指针方法,一个指针L从前向后遍历num1,另一个指针R从后向前遍历num2,这样可以保证乘积尽可能小。每一步中,计算可以配对的元素的数量(即两个计数中的最小值),并累加到结果中。指针移动至下一个非零计数位置继续配对,直到一个数组完全被遍历完毕。
时间复杂度: O(n + 100) = O(n)
空间复杂度: O(100) = O(1)
class Solution: def minProductSum(self, nums1: List[int], nums2: List[int]) -> int: num1 = [0] * 100 # 计数数组,记录nums1中元素的频率 num2 = [0] * 100 # 计数数组,记录nums2中元素的频率 for n1, n2 in zip(nums1, nums2): num1[n1-1] += 1 # 对应元素频率+1 num2[n2-1] += 1 # 对应元素频率+1 ans = 0 # 初始化最小乘积和 L, R = 0, 99 # 双指针初始化 while R >= 0: cnt = min(num1[L], num2[R]) # 找到当前两个元素的最小配对数量 ans += cnt * (L+1) * (R+1) # 计算当前配对的乘积和,累加到结果中 num1[L] -= cnt # 更新计数数组 num2[R] -= cnt # 更新计数数组 while L < 100 and num1[L] == 0: L += 1 # 移动L指针到下一个非零元素 while R >= 0 and num2[R] == 0: R -= 1 # 移动R指针到下一个非零元素 return ans # 返回最终的最小乘积和
Explore
计数排序被选用是因为它相比于传统的比较排序(如快速排序、归并排序等)在特定条件下有更低的时间复杂度。当输入的数字范围有限且固定(如1到100)时,计数排序的时间复杂度可以达到O(n),而传统排序算法的时间复杂度通常为O(n log n)。这种优化尤其在面对大量数据时显著,因此,在已知数据范围的情况下使用计数排序可以更有效率地处理数据。
在双指针法中,指针L从前向后移动,而指针R从后向前移动,这种策略确保了较小的数与较大的数相乘。由于L指针代表较小的数,R指针代表较大的数,这种配对方式可以使得乘积和尽可能小。通过选择最小的计数来配对,然后更新计数并适当移动指针,这种方法不断寻找当前可能的最小乘积和,从而确保了整体乘积和的最小性。
如果元素的范围变化,计数排序的数组长度应相应调整来匹配新的范围。例如,如果元素范围是1到500,计数数组的大小应扩展到500。对于更窄的范围,数组大小也应相应减小。此外,如果数据范围极大或不连续,可能需要考虑使用哈希表来进行计数,以保持空间效率和处理速度。
计数数组的长度选择为100是因为题目设定了元素大小在1到100之间。这意味着算法是专门为这一特定范围优化的。在应用到其他范围的数据时,算法需要相应调整计数数组的大小来适应新的元素范围。因此,虽然算法在当前形式下只适用于特定范围的数组,但通过调整可以使其适用于更广泛的情况。