DSA 中的丑陋数字

2025年3月17日 | 阅读 10 分钟

引言

丑数:数据结构与算法 (DSA) 中的一个概念,是对算法设计和动态规划中广泛使用的几个通用概念的有趣描述。一个丑数被描述为一个有效的整数,如果它的素因数只有 2、3 或 5。在规则中,一个丑数是其有效高级素因数是 2、3 或 5 的数。它可以表示为 (2a 乘以 3b 乘以 5c),其中 (a)、(b) 和 (c) 是非负整数。

这些非特异性数字在算法问题中很有用,特别是在优化和性能至关重要的情况下。“丑数”的概念通常用于动态规划搜索场景,以及涉及发现最丑变量或确定给定数字是否是丑数的情况。

非装饰数字的一个常见用途是排序相似数字。动态设计经常用于优化这些序列。算法可以设计为重复遍历数字,检查是否可以被 2、3 和 5 整除,并相应地更新数字的任意序列。这可以导致根据特定约束提供或调整信息的最佳答案。

此外,非修复数字在降低良好算法的时间复杂度方面发挥着作用。它们的设计允许动态过程反馈,通过对抗备用计算来减少典型计算时间。例如,您可以使用动态规划来查找最丑范围,而无需不断查看不同的优先级。

DSA 中丑数上述程序的实现有三种方法

方法 1:简单方法

循环所有正整数,直到丑数计数小于 n;如果一个整数是丑数,丑数计数也会增加。

要检查一个数字是否是丑数,请将该数字除以 2、3 和 5 的最大可分离幂。如果该数字变为 1,则它是一个丑数;否则,它不是。

例如,让我们看看如何检查 300 是否是丑数。2 的最大可分离幂是 4,将 300 除以 4 后,我们得到 75。3 的最大可分离幂是 3。将 75 除以 3 后,我们得到 25。5 的最大可分离幂是 25,将 25 除以 25 后,我们得到 1。由于我们最终得到 1,所以 300 是一个丑数。

简单方法的实现

输出

UGLY NUMBERS IN DSA

说明

提供的 Python 代码计算最丑数,其中“丑范围”定义为素因数仅限于 2、3 或 5 的高质量整数。maxDivide 特定是一个辅助点,它通过每个其他卷 b 的最佳可分离电力将各种 a 分割开来,直到它不再可分离。此函数用于通过将其除以其基本元素 2、3 和 5 来减小输入范围。

ugly 函数检查给定种类是否是丑数。它一遍又一遍地调用 maxDivide,通过 2、3 和 5 将范围划分开来,只要它仍然可被整除。但是,如果前一个范围变为 1,则意味着原始宽数字属于丑范围。

getNthUglyNo 函数计算最丑种类。它使用 while 循环通过整数重复,通过调用 isUgly 函数检查每个骨头是否是丑数。但是,如果它是长距离,则丑数的数量会增加。该系统一直运行,直到计数达到最不常见的数字。

在驱动程序代码中,调用 getNthUglyNo 函数,参数为 150,并勾勒出结果。结果表明,第 150 个丑数是分配给变量 no 的数字。该代码演示了一种通过迭代检查每个范围直到达到请求的丑数来查找丑数的简单系统。请注意,对于 n 的大值,此方法可能不是最有效的,因为它依赖于通过数字递增并检查丑陋程度。

这种方法在时间上效率不高,因为它会检查所有整数,直到丑数计数变为 n,但这种方法的空间复杂度是 O(1)

方法 2:使用动态方法

这里有一个时间高效的结果,具有 O(n) 的冗余空间。丑数序列是 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15,

因为每个数字只能被 2、3 或 5 整除,所以查看序列的一种方法是将其分解为三组,如下所示

(1 × 2, 2 × 2, 3 × 2, 4 × 2, 5 × 2,

(2) 1 × 3, 2 × 3, 3 × 3, 4 × 3, 5 × 3,

(3) 1 × 5, 2 × 5, 3 × 5, 4 × 5, 5 × 5,

我们可以发现每个子序列都是丑数序列本身(1, 2, 3, 4, 5)。乘以 2, 3, 5。此外,我们使用类似的合并系统或归并排序,从三个子序列中获取每个丑数。对于每一步,我们选择最小的一个并向后移动一步。

1:声明一个丑数数组 (n)

2:初始化第一个丑数 ugly(0) = 1

初始化三个数组指示器变量 (i2, i3, 和 i5) 指向

丑数数组的第一个元素

i2 = i3 = i5 = 0;

4:初始化 3 个下一个丑数的选择

= ugly(i2) * 2;

= ugly(i3) * 3

= ugly(i5) * 5;

5 现在循环填充所有丑数,直到 150。

对于 (i = 1; i < 150 i)

* 这些小方法没有针对良好进行优化

可读性。将在 C 程序中优化它们。

= Min (next_multiple_of_2,

next_multiple_of_3,

next_multiple_of_5);

ugly(i) = next_ugly_no

如果 (next_ugly_no == next_multiple_of_2)

i2 = i2 + 1;

= ugly(i2) * 2;

如果 (next_ugly_no == next_multiple_of_3)

i3 = i3 + 1;

= ugly(i3) * 3;

如果 (next_ugly_no == next_multiple_of_5)

i5 = i5 + 1;

= ugly(i5) * 5;

* 循环结束 */

6. 返回 next_ugly_no

示例

让我们看看它是如何工作的。

initialize

ugly() = | 1|

i2 = i3 = i5 = 0;

第一次复制

ugly(1) = Min(ugly(i2) * 2, ugly(i3) * 3, ugly(i5) * 5)

= Min (2, 3, 5)

= 2

ugly() = | 1| 2|

i2 = 1, i3 = 0, i5 = 0 (i2 已递增)。

交替复制

ugly(2) = Min (ugly(i2) * 2, ugly(i3) * 3, ugly(i5) * 5)

= Min (4, 3, 5)

= 3

ugly() = | 1| 2| 3|

i2 = 1, i3 = 1, i5 = 0 (i3 已递增)。

第三次复制

ugly(3) = Min(ugly(i2) * 2, ugly(i3) * 3, ugly(i5) * 5)

= Min (4, 6, 5)

= 4

ugly() = | 1| 2| 3| 4|

i2 = 2, i3 = 1, i5 = 0 (i2 已递增)。

第四次复制

ugly(4) = Min (ugly (i2) * 2, ugly (i3) * 3, ugly (i5) * 5)

= Min (6, 6, 5)

= 5

ugly() = | 1| 2| 3| 4| 5|

i2 = 2, i3 = 1, i5 = 1 (i5 已递增)。

第五次复制

ugly(4) = Min (ugly (i2) * 2, ugly (i3) * 3, ugly (i5) * 5)

= Min (6, 6, 10)

= 6

ugly() = | 1| 2| 3| 4| 5| 6|

i2 = 3, i3 = 2, i5 = 1(i2 和 i3 已递增)。

我将以同样的方式继续,直到 I < 150。

动态方法用法的实现

输出

UGLY NUMBERS IN DSA

说明

提供的 Python 软件有效地计算出最丑的宽数字,其中“丑数”被描述为主要因素仅限于 2、3 或 5 的巨大整数。getNthUglyNo 函数利用动态规划和合并数组的概念来推导最丑数,而无需一遍又一遍地检查可分性。

算法规则保持一个丑数数组到计算出的丑数。它将主细节 ugly(0) 初始化为 1,并且 3 个建议(i2、i3、i5)构成 2、3 和 5 的倍数的指标。变量 next_multiple_of_2、next_multiple_of_3 和 next_multiple_of_5 保持每个方面的以下能力:丑数。

循环遍历数组,通过选择可用的多个中的最小值为每个 ugly(l) 进行简化。因此,建议也会递增,并计算后续隐含的倍数。此过程有效地合并了 2、3 和 5 的排序倍数,确保数组始终包含最低的丑数。

在提供的示例中,驱动程序代码将 n 设置为 150 并调用 getNthUglyNo 点,打印结果,即第 150 个丑数。与许多其他暴力策略相比,这种方法最大限度地减少了计算,并确保了更快的丑数查找优化结果。

UGLY NUMBERS IN DSA

方法 3:使用 SET 数据结构

在此系统中,SET 数据结构存储生成的 3 个丑数中的最小值,这将是存储在集合第一个位置的丑数。SET 数据结构作为一个集合,按递增顺序存储所有元素

以下是上述方法的实现

集合使用方法的实现

输出

UGLY NUMBERS IN DSA

说明

上述 Python 实现使用基于固定集的方法计算第 n 个丑数。丑数定义为素因数仅限于 2、3 或 5 的有效整数。`nthUglyNumber` 函数最初处理 n 等于 1、2、3、4 或 5 的基本情况,返回 n 本身作为结果。

对于 n 大于 5 的情况,该特性使用第一个丑数 1 初始化列表 's'。然后它进入一个循环,迭代 n 次,用新的丑数更新集合 's'。

在循环中,算法规则从集合 's' 中提取主要元素 (`it`),删除它,并将集合转换为列表以方便排序。然后该特性将此细节乘以 2、3 和 5,并将结果再次添加到集合中。此集合保持丑数的有序列表。

循环完成后,该特性返回集合的顶部细节,表示第 n 个丑数。该集合充当动态框,用于正确处理和更新丑数,确保最佳顺序并避免不必要的重新计算。

在此示例中,驱动程序代码将 `n` 设置为 150 并调用 `nthUglyNumber` 特性,打印结果,即第 150 个丑数。该方法演示了一种使用集合生成丑数的不同方法,为问题提供了替代解决方案。

结论

最终,丑数,由其素因数仅限于 2、3 或 5 定义,在数据结构和算法 (DSA) 中具有重要意义。它们为算法挑战提供了实际程序,其中包括更改最丑的数或确定给定数的景象。迭代样式和动态规划等各种有效过程可以生成丑数序列。

合并排序数组的想法提供了一个优雅的结果,展示了如何成功地生成丑数而无需备用计算。丑数在优化和限制因子分解至关重要的情况下找到用武之地,为算法问题解决策略做出了贡献。

对丑数的观察和实施有助于更深入地理解数论,为算法优化策略提供宝贵的见解。它们独特的素因数约束使其成为探索和应用于不同算法问题的引人入胜的内容。总的来说,对丑数的考虑和操作丰富了算法工具包,增强了各种计算情况下的解决方案性能。