Java 中的星形数

2025年03月17日 | 阅读 9 分钟

在本节中,我们将学习 Java 中的星形数。星形数类似于中国跳棋棋盘。星形数是一个六角星。这里,六角星表示一个六角尖的星。请看下图。

Star Numbers in Java

在数学上,该数表示为

Sn = 6 x n x (n - 1) + 1,其中 n >= 1

因此,

S1 = 6 x 1 x (1 - 1) + 1 = 6 x 1 x 0 + 1 = 0 + 1 = 1

S2 = 6 x 2 x (2 - 1) + 1 = 6 x 2 x 1 + 1 = 12 + 1 = 13

S3 = 6 x 3 x (3 - 1) + 1 = 6 x 3 x 2 + 1 = 36 + 1 = 37

S4 = 6 x 4 x (4 - 1) + 1 = 6 x 4 x 3 + 1 = 72 + 1 = 73

S5 = 6 x 5 x (5 - 1) + 1 = 6 x 5 x 4 + 1 = 120 + 1 = 121

S6 = 6 x 6 x (6 - 1) + 1 = 6 x 6 x 5 + 1 = 180 + 1 = 181

实施

在 Java 中有三种方法可以编写星形数的代码。一种是使用上面定义的公式,另一种是递归,最后一种是迭代。让我们从基于公式的方法开始。

基于公式的方法

文件名:StarNumbers.java

输出

The first 10 star numbers are: 
1 13 37 73 121 181 253 337 433 541

时间复杂度:上述程序的时间复杂度为 O(n),其中 n 是要找到的星形数的总数。

空间复杂度:上述程序没有使用任何额外空间;因此,上述程序的空间复杂度为 O(1)。

递归方法

使用递归也可以计算星形数。但是,在实现递归之前,必须了解计算星形数的递归公式。递归公式定义为

Sn = Sn - 1 + 12 x (n - 1),其中 n >= 2 且 S1 = 1

因此,

S2 = S2 - 1 + 12 x (2 - 1) = S1 + 12 x 1 = 1 + 12 = 13

S3 = S3 - 1 + 12 x (3 - 1) = S2 + 12 x 2 = 13 + 24 = 37

S4 = S4 - 1 + 12 x (4 - 1) = S3 + 12 x 3 = 37 + 36 = 73

S5 = S5 - 1 + 12 x (5 - 1) = S4 + 12 x 4 = 73 + 48 = 121

S6 = S6 - 1 + 12 x (6 - 1) = S5 + 12 x 5 = 121 + 60 = 181

请看下面的 Java 代码。

文件名:StarNumbers1.java

输出

The first 10 star numbers are: 
1 13 37 73 121 181 253 337 433 541

时间复杂度:为了找到第 n 个星形数,必须递归地从 n 到 1。因此,上述程序的时间复杂度为 O(n2),其中 n 是要计算的星形数的总数。

空间复杂度:如果我们忽略由于递归引起的隐式内存消耗,则上述程序的空间复杂度为 O(1)。

为了优化上述程序,必须使用记忆化技术。以下程序显示了这一点。

文件名:StarNumbers2.java

输出

The first 10 star numbers are: 
1 13 37 73 121 181 253 337 433 541

时间复杂度:由于记忆化技术,上述程序的时间复杂度为 O(n),其中 n 是要计算的星形数的总数。

空间复杂度:上述程序的空间复杂度为 O(n),其中 n 是要计算的星形数的总数。

迭代方法

使用循环也可以轻松计算星形数的值。以下程序显示了这一点。

文件名:StarNumbers3.java

输出

The first 10 star numbers are: 
1 13 37 73 121 181 253 337 433 541

时间复杂度:由于在计算每个星形数时使用了 for 循环,因此上述程序的时间复杂度为 O(n2),其中 n 是要找到的星形数的总数。

空间复杂度:上述程序的空间复杂度为 O(n),其中 n 是要计算的星形数的总数。

我们可以优化上述代码以降低时间复杂度。请看以下程序。

文件名:StarNumbers4.java

输出

The first 10 star numbers are: 
1 13 37 73 121 181 253 337 433 541

时间复杂度:由于只有一个循环用于计算星形数;因此,上述程序的时间复杂度为 O(n),其中 n 是要找到的星形数的总数。

空间复杂度:上述程序的空间复杂度为 O(n),其中 n 是要计算的星形数的总数。

我们仍然可以做一些优化以减少程序的空间复杂度。如果我们观察递归公式,我们会发现第 n 个星形数依赖于第 (n - 1) 个星形数,而第 (n - 1) 个星形数依赖于第 (n - 2) 个星形数,依此类推。这意味着当前的星形数依赖于前一个星形数。因此,我们不需要数组来存储星形数。我们所要做的就是将前一个星形数存储在一个变量中以计算当前星形数。以下程序显示了这一点。

文件名:StarNumbers5.java

输出

The first 10 star numbers are: 
1 13 37 73 121 181 253 337 433 541

时间复杂度:由于只有一个循环用于计算星形数;因此,上述程序的时间复杂度为 O(n),其中 n 是要找到的星形数的总数。

空间复杂度:由于我们只使用两个变量来计算星形数;因此,上述程序的空间复杂度为 O(1)。

与其他数字的关系

  • 有许多星形数也是三角形数。例如 1、253、49141 等等,都是星形数和三角形数。
  • 有许多星形数也是平方数。例如 1 = 12、121 = 112、11881 = 1092 等等,都是星形数和平方数。
  • 星形素数是指既是素数又是星形数的数字。例如:13、37、73 等等,都是星形数和素数。