判断一个数是否迷人

标签: 哈希表 数学

难度: Easy

给你一个三位数整数 n 。

如果经过以下修改得到的数字 恰好 包含数字 1 到 9 各一次且不包含任何 0 ,那么我们称数字 n 是 迷人的 :

  • 将 n 与数字 2 * n 和 3 * n 连接 。

如果 n 是迷人的,返回 true,否则返回 false 。

连接 两个数字表示把它们首尾相接连在一起。比方说 121 和 371 连接得到 121371 。

示例 1:

输入:n = 192
输出:true
解释:我们将数字 n = 192 ,2 * n = 384 和 3 * n = 576 连接,得到 192384576 。这个数字包含 1 到 9 恰好各一次。

示例 2:

输入:n = 100
输出:false
解释:我们将数字 n = 100 ,2 * n = 200 和 3 * n = 300 连接,得到 100200300 。这个数字不符合上述条件。

提示:

  • 100 <= n <= 999

Submission

运行时间: 17 ms

内存: 16.0 MB

class Solution:
    def isFascinating(self, n: int) -> bool:
        n = str(n) + str(2 * n) + str(3 * n)
        return "0" not in n and len(n) == 9 and len(n) == len(set(n))

Explain

此题解首先计算输入的三位数n、2n和3n的值,然后将这些数字转换为字符串并连接起来。接着,检查生成的字符串是否恰好包含数字1到9各一次且不包含数字0。具体步骤包括:1) 检查字符串中是否包含'0';2) 检查字符串长度是否为9;3) 检查字符串中的所有字符是否都是唯一的(通过将字符串转换为集合并比较长度来实现)。如果这三个条件都满足,返回true,否则返回false。

时间复杂度: O(1)

空间复杂度: O(1)

class Solution:
    def isFascinating(self, n: int) -> bool:
        # 将n, 2n, 3n转换为字符串并连接
        n = str(n) + str(2 * n) + str(3 * n)
        # 检查生成的字符串是否符合条件:不包含'0',长度为9,所有字符都是唯一的
        return "0" not in n and len(n) == 9 and len(n) == len(set(n))

Explore

使用集合来判断字符串中的字符是否唯一是一种简单而高效的方法。使用集合,我们可以直接插入每个字符,并利用集合的属性(不允许重复元素)来确保所有字符都是唯一的。如果使用排序,虽然可以通过比较相邻字符来检查重复,但排序本身通常具有O(n log n)的时间复杂度,比转换为集合并检查长度(大致为O(n)的时间复杂度)更耗时。此外,使用集合的方法代码更简洁,易于理解和维护。

如果输入的三位数n是以0结尾的,例如230,其2n为460,3n为690。虽然这些乘积仍然是三位数,但问题的关键在于最终生成的字符串是否正确地包含了1至9的每个数字恰好一次。在这个特定的例子中,即便n、2n和3n都是三位数,生成的字符串仍然可以满足长度为9的要求。然而,如果n、2n或3n中的任何一个乘积结果导致长度不为三位数(如数值较小),则会影响字符串的总长度,从而影响算法的判断。

将字符串转换为集合并比较长度的方法通常是可靠的,前提是我们已经确保了字符串不包含不应存在的字符(例如数字0或超过9的数字)。这种方法的关键在于它假定输入字符串只包含目标字符集(1至9)。如果字符串包含任何非目标字符或目标字符重复,长度检查将会失败。因此,只要前置条件满足(不包含数字0,且字符串长度为9),这种方法就是可靠的。

如果n不是三位数,比如一位或两位数,这个算法可能无法正确运行,因为n、2n和3n生成的字符串可能不会达到9个字符的长度,从而无法包含所有从1到9的数字。为了修改算法适应任意位数的整数,我们可以引入一个循环或递归机制,不断增加乘数直到生成的字符串长度至少为9,并在此过程中检查生成的字符串是否满足包含1到9的数字恰好一次的条件。这样可以确保算法能适用于不同长度的整数输入。