返回

立足基础 算法题解 — LeetCode 第 633 题:平方数之和

前端

一、题目

给定一个非负整数 c,你要判断是否存在两个整数 ab,使得 a^2 + b^2 = c

二、数学知识

为了解决这个问题,我们需要用到一些数学知识。

首先,我们知道任何一个正整数都可以表示为若干个质数的乘积。例如,12 可以表示为 2^2 * 3。

其次,我们知道任何一个正整数的平方都可以表示为若干个质数的偶次幂的乘积。例如,16 可以表示为 2^4。

最后,我们知道任何一个正整数的平方和都可以表示为若干个质数的奇次幂的乘积。例如,25 可以表示为 5^2。

三、数学证明

现在,我们来证明一下,如果一个整数能够表示为两个整数的平方和,那么它一定满足一定的条件。

假设整数 c 能够表示为两个整数 ab 的平方和,即 c = a^2 + b^2

那么,c 一定可以表示为若干个质数的乘积。

因为 a^2b^2 都可以表示为若干个质数的偶次幂的乘积,所以 c = a^2 + b^2 也一定可以表示为若干个质数的偶次幂的乘积。

但是,我们知道,任何一个正整数的平方和都只能表示为若干个质数的奇次幂的乘积。

所以,c 不可能表示为两个整数的平方和。

四、编程实现

我们可以使用两种方法来编程实现这个问题。

方法一:枚举

第一种方法是枚举所有可能的 ab 的值,并计算 a^2 + b^2 的值,看看是否等于 c

def judge_square_sum(c):
  """
  判断一个整数能否表示为两个整数的平方和。

  Args:
    c: 一个非负整数。

  Returns:
    如果能够表示,返回 True;否则,返回 False。
  """

  for a in range(1, c + 1):
    for b in range(1, c + 1):
      if a * a + b * b == c:
        return True

  return False

方法二:数学性质

第二种方法是利用我们前面证明的数学性质,直接判断 c 是否满足一定的条件。

def judge_square_sum(c):
  """
  判断一个整数能否表示为两个整数的平方和。

  Args:
    c: 一个非负整数。

  Returns:
    如果能够表示,返回 True;否则,返回 False。
  """

  while c % 4 == 0:
    c //= 4

  if c % 8 == 7:
    return False

  for a in range(1, int(c ** 0.5) + 1):
    if a * a > c:
      break

    b = (c - a * a) ** 0.5

    if b == int(b):
      return True

  return False

五、代码优化

我们可以对代码进行优化,使之更加高效。

一种优化方法是减少枚举的次数。我们可以先计算出 c 的所有质因子,然后枚举这些质因子的不同次幂的乘积。这样,我们可以减少枚举的次数,从而提高算法的效率。

另一种优化方法是使用二分查找来寻找 b 的值。这样,我们可以减少比较的次数,从而提高算法的效率。

六、复杂度分析

方法一:枚举

枚举所有可能的 ab 的值,并计算 a^2 + b^2 的值,看看是否等于 c

时间复杂度:O(n^2)。

空间复杂度:O(1)。

方法二:数学性质

利用我们前面证明的数学性质,直接判断 c 是否满足一定的条件。

时间复杂度:O(sqrt(c))。

空间复杂度:O(1)。

七、总结

我们已经学习了如何解决 LeetCode 第 633 题「平方数之和」。我们首先分析了这个问题的数学性质,证明了如果一个整数能够表示为两个整数的平方和,那么它一定满足一定的条件。然后,我们给出了两种编程实现,并分析了它们的复杂度。最后,我们对代码进行了优化,使之更加高效。