给你一个下标从 0 开始的数组 nums
,数组长度为 n
。
nums
的 不同元素数目差 数组可以用一个长度为 n
的数组 diff
表示,其中 diff[i]
等于前缀 nums[0, ..., i]
中不同元素的数目 减去 后缀 nums[i + 1, ..., n - 1]
中不同元素的数目。
返回 nums
的 不同元素数目差 数组。
注意 nums[i, ..., j]
表示 nums
的一个从下标 i
开始到下标 j
结束的子数组(包含下标 i
和 j
对应元素)。特别需要说明的是,如果 i > j
,则 nums[i, ..., j]
表示一个空子数组。
示例 1:
输入:nums = [1,2,3,4,5] 输出:[-3,-1,1,3,5] 解释: 对于 i = 0,前缀中有 1 个不同的元素,而在后缀中有 4 个不同的元素。因此,diff[0] = 1 - 4 = -3 。 对于 i = 1,前缀中有 2 个不同的元素,而在后缀中有 3 个不同的元素。因此,diff[1] = 2 - 3 = -1 。 对于 i = 2,前缀中有 3 个不同的元素,而在后缀中有 2 个不同的元素。因此,diff[2] = 3 - 2 = 1 。 对于 i = 3,前缀中有 4 个不同的元素,而在后缀中有 1 个不同的元素。因此,diff[3] = 4 - 1 = 3 。 对于 i = 4,前缀中有 5 个不同的元素,而在后缀中有 0 个不同的元素。因此,diff[4] = 5 - 0 = 5 。
示例 2:
输入:nums = [3,2,3,4,2] 输出:[-2,-1,0,2,3] 解释: 对于 i = 0,前缀中有 1 个不同的元素,而在后缀中有 3 个不同的元素。因此,diff[0] = 1 - 3 = -2 。 对于 i = 1,前缀中有 2 个不同的元素,而在后缀中有 3 个不同的元素。因此,diff[1] = 2 - 3 = -1 。 对于 i = 2,前缀中有 2 个不同的元素,而在后缀中有 2 个不同的元素。因此,diff[2] = 2 - 2 = 0 。 对于 i = 3,前缀中有 3 个不同的元素,而在后缀中有 1 个不同的元素。因此,diff[3] = 3 - 1 = 2 。 对于 i = 4,前缀中有 3 个不同的元素,而在后缀中有 0 个不同的元素。因此,diff[4] = 3 - 0 = 3 。
class Solution:
def distinctDifferenceArray(self, nums: List[int]) -> List[int]:
st = set() # 用于记录后缀中不同的元素
sufCnt = [0] * (len(nums) + 1) # 后缀不同元素数量数组
# 计算每个后缀的不同元素数量
for i in range(len(nums) - 1, 0, -1):
st.add(nums[i])
sufCnt[i] = len(st)
res = [] # 结果数组
st.clear() # 清空集合,准备计算前缀不同元素数量
# 计算结果数组
for i in range(len(nums)):
st.add(nums[i])
res.append(len(st) - sufCnt[i + 1])
return res
假设
nums = [1, 2, 3, 4, 2]
,我们来逐步解释代码的工作过程:
计算后缀不同元素数量:
- 初始化
st
为一个空集合,sufCnt
初始化为[0, 0, 0, 0, 0, 0]
。- 从
i = 4
开始向前遍历:
i = 4
:st = {2}
,sufCnt[4] = 1
i = 3
:st = {2, 4}
,sufCnt[3] = 2
i = 2
:st = {2, 3, 4}
,sufCnt[2] = 3
i = 1
:st = {1, 2, 3, 4}
,sufCnt[1] = 4
- 最终
sufCnt
为[0, 4, 3, 2, 1, 0]
计算前缀不同元素数量并得到结果:
- 初始化
st
为一个空集合,res
初始化为空。- 从
i = 0
开始向后遍历:
i = 0
:st = {1}
,res.append(len(st) - sufCnt[1])
,即1 - 4 = -3
i = 1
:st = {1, 2}
,res.append(len(st) - sufCnt[2])
,即2 - 3 = -1
i = 2
:st = {1, 2, 3}
,res.append(len(st) - sufCnt[3])
,即3 - 2 = 1
i = 3
:st = {1, 2, 3, 4}
,res.append(len(st) - sufCnt[4])
,即4 - 1 = 3
i = 4
:st = {1, 2, 3, 4}
(sufCnt[5]
为 0)res.append(len(st) - sufCnt[5])
,即4 - 0 = 4
- 最终
res
为[-3, -1, 1, 3, 4]
这个算法的时间复杂度为 (O(n)),因为每个元素在前缀和后缀集合中最多被处理两次。