Java 中的直线数

2024 年 9 月 10 日 | 阅读 7 分钟

如果一个数字 n 的各位数字构成一个等差数列,则称该数字为直线数。很明显,要判断各位数字是否构成等差数列,至少需要三位数字。因此,直线数应始终包含至少三位数字,且不包含前导零。

示例 1

输入: N = 178

输出: 否,178 不是直线数。

解释: 数字 178 的各位数字是 1、7、8。7 - 1 = 6,8 - 7 = 1。因此,公差不相同,各位数字不构成等差数列。因此,178 不是直线数。

示例 2

输入: N = 111

输出: 是,111 是直线数。

解释: 数字 111 的各位数字是 1、1、1。1 - 1 = 0,1 - 1 = 0。因此,公差相同,各位数字构成等差数列。因此,111 是直线数。

示例 3

输入: N = 25

输出: 否,25 不是直线数。

解释: 数字 25 的各位数字是 2 和 5。两位数字不足以判断它们是否构成等差数列。因此,25 不是直线数。

朴素方法

方法很简单。首先,我们将数字的所有各位数字存储在一个数组中。然后,使用循环,我们可以从左到右或从右到左迭代,找到两个相邻元素之间的差值。如果所有两个相邻元素之间的差值都相同,那么我们可以说该数字是直线数;否则,它就不是。

文件名: StraightLineNumbersNaive.java

输出

No, 178 is not a Straight Line number.
Yes, 111 is a Straight Line number.
No, 25 is not a Straight Line number.

复杂度分析: 程序中使用的循环会一直迭代直到探索完数字的所有各位数字。因此,程序的时间复杂度为 O(d)。程序还将数字存储在 ArrayList 中,因此程序空间复杂度为 O(d),其中 d 是输入数字中存在的总位数。

方法:使用字符串

在此方法中,我们首先需要将数字转换为字符串。然后,我们可以迭代字符以查找它们是否构成等差数列,并据此决定它们是否是直线数。以下程序对此进行了说明。

文件名: StraightLineNumbersStr.java

输出

No, 178 is not a Straight Line number.
Yes, 111 is a Straight Line number.
No, 25 is not a Straight Line number.

复杂度分析:程序的 time complexity 和 space complexity 与上一个程序相同。

我们可以避免使用字符串和 ArrayList 来降低空间复杂度。以下对此进行了说明。

文件名: StraightLineNumbersOptimized.java

输出

No, 178 is not a Straight Line number.
Yes, 111 is a Straight Line number.
No, 25 is not a Straight Line number.

复杂度分析:程序的 time complexity 和 space complexity 与上一个程序相同。

输出

No, 178 is not a Straight Line number.
Yes, 111 is a Straight Line number.
No, 25 is not a Straight Line number.

复杂度分析: 程序的时间复杂度为 O(d),其中 d 是数字中的总位数。程序空间复杂度为 O(1)。

查找范围内的直线数

在本节中,我们将介绍如何过滤范围内的直线数。

文件名: StraightLineNumbersRange.java

输出

Straight Line Numbers from range 100 and 1000 are:
111 123 135 147 159 210 222 234 246 258 321 333 345 357 369 420 432 444 456 468 531 543 555 567 579 630 642 654 666 678 741 753 765 777 789 840 852 864 876 888 951 963 975 987 999