反转之后不同整数的数目

标签: 数组 哈希表 数学

难度: Medium

给你一个由 整数组成的数组 nums

你必须取出数组中的每个整数,反转其中每个数位,并将反转后得到的数字添加到数组的末尾。这一操作只针对 nums 中原有的整数执行。

返回结果数组中 不同 整数的数目。

示例 1:

输入:nums = [1,13,10,12,31]
输出:6
解释:反转每个数字后,结果数组是 [1,13,10,12,31,1,31,1,21,13] 。
反转后得到的数字添加到数组的末尾并按斜体加粗表示。注意对于整数 10 ,反转之后会变成 01 ,即 1 。
数组中不同整数的数目为 6(数字 1、10、12、13、21 和 31)。

示例 2:

输入:nums = [2,2,2]
输出:1
解释:反转每个数字后,结果数组是 [2,2,2,2,2,2] 。
数组中不同整数的数目为 1(数字 2)。

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 106

Submission

运行时间: 153 ms

内存: 41.8 MB

class Solution:
    def countDistinctIntegers(self, nums: List[int]) -> int:
        for i in range(len(nums)):
            nums.append(int(str(nums[i])[::-1]))
        return len(set(nums))

Explain

该题解采用了直接的方法来解决问题。首先,遍历数组 nums 中的每个整数,将其转换为字符串,然后反转字符串,并将反转后的字符串再转换回整数。这些反转后的整数被添加到原始数组 nums 的末尾。利用 Python 的 set 数据结构,可以自动过滤掉重复的元素,因此最后返回 set(nums) 的长度即可得到不同整数的数目。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def countDistinctIntegers(self, nums: List[int]) -> int:
        # 遍历原始数组中的每个数字
        for i in range(len(nums)):
            # 将数字转换为字符串,反转,并转换回整数后添加到数组末尾
            nums.append(int(str(nums[i])[::-1]))
        # 利用 set 集合去重,并返回不同数字的数量
        return len(set(nums))

Explore

在题解的实现中,将反转后的整数添加到原始数组 nums 的末尾确实可能会影响遍历过程,因为这种操作改变了数组的长度。然而,在此题解的 for 循环中,循环的终止条件是固定的,即在循环开始前就通过 len(nums) 确定,这意味着遍历的范围不会因为数组长度的增加而改变。因此,尽管数组长度增加了,但遍历的次数是基于原始数组的长度,不会遍历到新增的反转后的整数。

在 Python 中,将字符串转换为整数时,前导零会自动被忽略。例如,字符串 '01' 在转换为整数时会变成 1。因此,在题解中,通过 str(nums[i])[::-1] 反转字符串并用 int() 函数转换回整数时,自动处理了前导零的问题,不需要特殊的处理措施。

Python 中的 set 是基于哈希表实现的,这使得其在插入和查找操作上的平均时间复杂度为 O(1)。然而,当处理大量数据时,哈希表可能需要多次重新哈希以调整大小,这可能会导致性能下降,特别是在内存受限的情况下。此外,哈希冲突的增加也可能降低性能。尽管 set 的去重操作通常效率较高,但在极端情况下,性能可能会成为瓶颈。

如果数组 nums 非常大,当前的方法可能不是最优的。首先,数组长度的增加导致内存消耗增加,因为反转的整数被添加到数组中,实际上使数组大小翻倍。其次,遍历和反转操作本身就需要 O(n) 时间。一种更高效的方法可能是先计算出所有反转的整数,然后将这些整数与原始数组合并,一次性转换为 set,避免了数组大小的翻倍,也减少了不必要的内存占用。