Java 中的自描述数

10 Sept 2024 | 5 分钟阅读

给定一个数字 n。我们的任务是找出 1 到 n 之间的自描述数字。

自描述数字

自描述数字 m 是一个在 b 进制下有 b 个数字的数字,其中最高有效数字位于 0 位,最低有效数字位于 b - 1 位(从左到右,零索引,类似于数组)。此外,位于 n 处的每个数字 d,都计数数字 n 在 m 中出现的次数。观察以下示例。

示例 1

m = 2020

输出: 2020 是一个自描述数字。

解释: 由于数字 2020 只有 4 位,因此考虑使用 4 进制。数字 2 位于 0 位,表示 0 出现了两次。数字 0 位于 1 位,表示 1 出现了零次。再次,数字 2 位于 2 位,表示 2 出现了两次。之后,数字 0 放在 3 位,表示 3 出现了零次。如果我们查看数字,会发现

0 出现了两次。2 出现了两次。此外,1 和 3 出现了零次。因此,上面段落中写的所有陈述都是正确的。因此,2020 是一个自描述数字。

示例 2

m = 6210001000

输出: 6210001000 是一个自描述数字。

解释: 由于数字 2020 只有 10 位,因此考虑使用 10 进制。数字 6 位于 0 位,表示 0 出现了六次。数字 2 位于 1 位,表示 1 出现了两次。再次,数字 1 位于 2 位,表示 2 出现了一次。之后,数字 0 放在 3 位、4 位、5 位、7 位、8 位和 9 位,表示数字 3、4、5、7、8 和 9 出现了零次。在 6 位,我们看到数字 1,表示 6 出现了一次。如果我们查看数字,会发现

6 出现了一次。2 出现了一次。1 出现了两次。2 出现了一次,0 出现了六次。此外,3、4、5、7、8 和 9 出现了零次。因此,上面段落中写的所有陈述都是正确的。因此,6210001000 是一个自描述数字。

实现: 使用嵌套循环

观察以下查找自描述数字的程序。

文件名: SelfDescriptive.java

输出

In the range 1 to 100000, we have the following self-descriptive numbers.
1210
2020
21200

解释: 在外层循环中,每次迭代都会提取所有数字并将其保存在变量 v 中。然后,在内层循环中,有一个变量 cnt 用于计算数字 j(此 j 是外层循环的 jth 索引)在字符串中出现的次数。最终,将变量 cnt 与变量 v 进行比较。如果比较不匹配,则返回 false 值。

复杂度分析: 程序的 time complexity 为 O(n * len(n) * len(n))。 space complexity 为 O(1)。

如果我们进行一些预处理,将数字的频率存储在一个数组中,那么我们可以降低程序的复杂度。下面程序中给出了该方法的说明。

文件名: SelfDescriptive1.java

输出

In the range 1 to 100000, we have the following self-descriptive numbers.
1210
2020
21200

复杂度分析: 程序的 time complexity 为 O(n * len(n))。 space complexity 为 O(1)。有人可能会争辩说我们使用了辅助数组。然而,辅助数组的大小为 10,并且在任何情况下都不会改变。因此,我们可以说辅助数组的大小是固定的,使得 space complexity 为 O(1)。