📌  相关文章
📜  查找数组中所有唯一元素的总和,以进行K个查询(1)

📅  最后修改于: 2023-12-03 14:55:34.426000             🧑  作者: Mango

查找数组中所有唯一元素的总和,以进行K个查询

问题描述

给定一个数组,找到其中所有唯一元素的总和。然后,对于K个查询,每次查询将给出两个数字,您需要找到位于该范围内的唯一元素的总和。

解决方案
思路
  1. 遍历整个数组,使用一个哈希表来计算每个元素出现的次数。
  2. 再次遍历整个数组,将所有出现次数为1的元素的值加起来,得到唯一元素的总和。
  3. 对于每次查询,可以使用一个类似于前缀和(prefix sum)的技巧来计算指定范围内唯一元素的总和。具体地,我们预处理出“前缀唯一元素总和”,即前n个元素中唯一元素的总和。然后,对于每个查询,我们只需要计算指定范围(从a到b)中所有唯一元素的总和,即前b个元素的唯一元素总和减去前a-1个元素的唯一元素总和。
  4. 时间复杂度:O(N)预处理 + O(K)查询 = O(N+K)。
代码实现
def unique_sum(arr):
    # step 1: 计算每个元素出现的次数
    freq = {}
    for num in arr:
        freq[num] = freq.get(num, 0) + 1

    # step 2: 计算唯一元素的总和
    unique_sum = 0
    for num, count in freq.items():
        if count == 1:
            unique_sum += num

    return unique_sum

def unique_sum_range(arr, queries):
    # step 1: 预处理前缀唯一元素总和
    prefix_unique_sum = [0] * (len(arr)+1)
    freq = {}
    for i in range(1, len(arr)+1):
        num = arr[i-1]
        freq[num] = freq.get(num, 0) + 1
        if freq[num] == 1:
            prefix_unique_sum[i] = prefix_unique_sum[i-1] + num
        elif freq[num] == 2:
            prefix_unique_sum[i] = prefix_unique_sum[i-1] - num
        else:
            prefix_unique_sum[i] = prefix_unique_sum[i-1]

    # step 2: 对每个查询计算唯一元素的总和
    res = []
    for q in queries:
        a, b = q
        res.append(prefix_unique_sum[b] - prefix_unique_sum[a-1])

    return res
示例
arr = [1, 2, 3, 2, 1, 4, 5]
queries = [(1, 4), (2, 6), (1, 7)]
print(unique_sum(arr))      # Output: 12
print(unique_sum_range(arr, queries))  # Output: [8, 8, 12]
复杂度分析
  • 时间复杂度:O(N+K),其中N是数组长度,K是查询次数。
  • 空间复杂度:O(N),用于存储前缀唯一元素总和数组。