📌  相关文章
📜  执行给定操作后数组中唯一值的最大数量(1)

📅  最后修改于: 2023-12-03 15:39:43.136000             🧑  作者: Mango

执行给定操作后数组中唯一值的最大数量

问题描述

假设有一个整数数组 nums,我们可以对其中一个元素进行以下操作:

  • 将该元素替换为任意整数 x 。
  • 如果操作后 nums 中所有元素都是唯一的,则称此操作为“有效操作”。

给定 nums,你的任务是执行任意数量的有效操作,并返回数组中可以通过执行操作得到的最大长度。

示例 1:

输入:nums = [5,6,8,8,5] 输出:3 解释:可以执行操作 [1,2,3],将第一个,第二个和第三个元素替换为 7,7 和 10 。

示例 2:

输入:nums = [1,2,3,4,5,6,7,8,9,10] 输出:10 解释:可以执行操作 [ ] ,不能执行任何操作。

解决方案

我们可以首先遍历数组 nums,统计每个元素出现的次数。对于出现了 k 次的元素,我们最多可以将 k-1 个这样的元素通过操作变成一个唯一的数。

例如,对于示例 1 中的数组 [5,6,8,8,5],元素 5 和元素 8 都出现了两次。我们最多可以将它们都修改为不同的数,这样整个数组中的数字就都是唯一的了。因此,我们可以执行的有效操作数为 2 + 2 = 4。

但是,如果数组中存在大量出现次数很多的元素,上述解决方案的时间复杂度会很高。因此,我们可以使用优先队列。具体的思路如下:

  1. 遍历数组 nums,统计每个元素出现的次数。
  2. 将所有出现次数大于 1 的元素加入优先队列中。
  3. 从优先队列中取出出现次数最多的元素,不断将该元素的出现次数减 1,并将减 1 后的次数重新加入优先队列中。直到队列为空。
  4. 在第 3 步的过程中,我们可以记录出队的元素个数,并将它们的出现次数相加得到我们最多可以执行的有效操作数。
代码实现
import heapq
from typing import List

class Solution:
    def maximumUniqueSubarray(self, nums: List[int]) -> int:
        freq = {}
        for num in nums:
            freq[num] = freq.get(num, 0) + 1
        
        max_heap = []
        for key in freq:
            if freq[key] > 1:
                heapq.heappush(max_heap, -freq[key])
    
        cur_sum = 0
        max_len = 0
        visited = set()
        for num in nums:
            if freq[num] == 1 and num not in visited:
                visited.add(num)
                cur_sum += num
                max_len = max(max_len, cur_sum)
            else:
                while max_heap and freq[num] > 1:
                    cnt = -heapq.heappop(max_heap)
                    if cnt <= freq[num] - 1:
                        freq[num] -= cnt
                        cur_sum += cnt * num
                    else:
                        heapq.heappush(max_heap, -(cnt - freq[num] + 1))
                        freq[num] = 1
                        cur_sum += (freq[num] - 1) * num
                if freq[num] == 1 and num not in visited:
                    visited.add(num)
                    cur_sum += num
                    max_len = max(max_len, cur_sum)
        
        return max_len
参考链接