📌  相关文章
📜  检查一个数是否可以表示为 2 个三角形数的和(1)

📅  最后修改于: 2023-12-03 14:55:43.414000             🧑  作者: Mango

检查一个数是否可以表示为 2 个三角形数的和

在数论中,一个三角形数可以表示为一个等差数列的和,而这个等差数列的公差为1。可表示为以下公式:

$$T_n = \frac{n(n+1)}{2}$$

例如:

T1 = 1
T2 = 1 + 2 = 3
T3 = 1 + 2 + 3 = 6
T4 = 1 + 2 + 3 + 4 = 10
T5 = 1 + 2 + 3 + 4 + 5 = 15

我们的目标是检查一个数是否可以表示为两个三角形数的和。

暴力法

最简单粗暴的思路是枚举每对三角形数 $T_i$ 和 $T_j$。时间复杂度为 $O(n^2)$。两个三角形数的和可以表示成如下的表达式:

$$T_i + T_j = \frac{i(i+1)}{2} + \frac{j(j+1)}{2} = \frac{(i+j)(i+j+1)}{2}$$

代码
def check_triangle_number(n):
    for i in range(1, n+1):
        for j in range(1, n+1):
            if (i*(i+1) + j*(j+1))//2 == n:
                return True
    return False
时间复杂度

$O(n^2)$

双指针法

上面的方法虽然可以达到目的,但时间复杂度实在是太高了。我们可以用双指针法来解决这个问题。首先确定最小的三角形数 $T_i$,这里我们可以简单的将 $T_i = 1$,然后另外一个三角形数 $T_j$ 从 $T_{i+1}$ 开始。如果这个和小于 $n$,则 $T_j$ 指针向右移动,如果这个和大于 $n$,则 $T_i$ 指针向右移动。

代码
def check_triangle_number(n):
    i, j = 1, 1
    while i*(i+1)//2 < n:
        while j*(j+1)//2 < n:
            s = i*(i+1)//2 + j*(j+1)//2
            if s == n:
                return True
            elif s > n:
                break
            j += 1
        i += 1
        j = i
    return False
时间复杂度

$O(n)$

以上两种方法都可以检查一个数是否可以表示为两个三角形数的和,但双指针法更加高效。