Skip to content

feat: add solutions to lc problem: No.0633 #3118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 18, 2024
134 changes: 134 additions & 0 deletions solution/0600-0699/0633.Sum of Square Numbers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,138 @@ impl Solution {

<!-- solution:end -->

<!-- solution:start -->

### 方法二:数学

这个问题实际上是关于一个数能否表示为两个平方数之和的条件。这个定理可以追溯到费马(Fermat)和欧拉(Euler),它在数论中是一个经典结果。

具体来说,这个定理可以表述为:

**一个正整数 \( n \) 能表示为两个平方数之和的充要条件是:\( n \) 的所有形如 \( 4k + 3 \) 的素数因子的幂次均为偶数。**

这意味着,如果我们将 $n$ 分解成素数因子乘积的形式,即 $n = p_1^{e_1} p_2^{e_2} \cdots p_k^{e_k}$,其中 $p_i$ 是素数且 $e_i$ 是它们对应的幂次,那么 $n$ 可以表示为两个平方数之和,当且仅当所有 $4k + 3$ 形式的素数因子 $p_i$ 的幂次 $e_i$ 都是偶数。

更正式地,假设 $p_i$ 是形如 $4k + 3$ 的素数,则对于每一个这样的 $p_i$,要求 $e_i$ 是偶数。

例如:

- 数字 $13$ 是素数,且 $13 \equiv 1 \pmod{4}$,因此它可以表示为两个平方数之和,即 $13 = 2^2 + 3^2$。
- 数字 $21$ 分解为 $3 \times 7$,其中 $3$ 和 $7$ 都是形如 $4k + 3$ 的素数因子,并且它们的幂次都是 $1$(奇数),因此 $21$ 不能表示为两个平方数之和。

总结起来,这个定理在数论中非常重要,用于判断一个数是否可以表示为两个平方数之和。

时间复杂度 $O(\sqrt{c})$,其中 $c$ 是给定的非负整数。空间复杂度 $O(1)$。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def judgeSquareSum(self, c: int) -> bool:
for i in range(2, int(sqrt(c)) + 1):
if c % i == 0:
exp = 0
while c % i == 0:
c //= i
exp += 1
if i % 4 == 3 and exp % 2 != 0:
return False
return c % 4 != 3
```

#### Java

```java
class Solution {
public boolean judgeSquareSum(int c) {
int n = (int) Math.sqrt(c);
for (int i = 2; i <= n; ++i) {
if (c % i == 0) {
int exp = 0;
while (c % i == 0) {
c /= i;
++exp;
}
if (i % 4 == 3 && exp % 2 != 0) {
return false;
}
}
}
return c % 4 != 3;
}
}
```

#### C++

```cpp
class Solution {
public:
bool judgeSquareSum(int c) {
int n = sqrt(c);
for (int i = 2; i <= n; ++i) {
if (c % i == 0) {
int exp = 0;
while (c % i == 0) {
c /= i;
++exp;
}
if (i % 4 == 3 && exp % 2 != 0) {
return false;
}
}
}
return c % 4 != 3;
}
};
```

#### Go

```go
func judgeSquareSum(c int) bool {
n := int(math.Sqrt(float64(c)))
for i := 2; i <= n; i++ {
if c%i == 0 {
exp := 0
for c%i == 0 {
c /= i
exp++
}
if i%4 == 3 && exp%2 != 0 {
return false
}
}
}
return c%4 != 3
}
```

#### TypeScript

```ts
function judgeSquareSum(c: number): boolean {
const n = Math.floor(Math.sqrt(c));
for (let i = 2; i <= n; ++i) {
if (c % i === 0) {
let exp = 0;
while (c % i === 0) {
c /= i;
++exp;
}
if (i % 4 === 3 && exp % 2 !== 0) {
return false;
}
}
}
return c % 4 !== 3;
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
134 changes: 134 additions & 0 deletions solution/0600-0699/0633.Sum of Square Numbers/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,138 @@ impl Solution {

<!-- solution:end -->

<!-- solution:start -->

### Solution 2: Mathematics

This problem is essentially about the conditions under which a number can be expressed as the sum of two squares. This theorem dates back to Fermat and Euler and is a classic result in number theory.

Specifically, the theorem can be stated as follows:

> A positive integer $n$ can be expressed as the sum of two squares if and only if all prime factors of $n$ of the form $4k + 3$ have even powers.

This means that if we decompose $n$ into the product of its prime factors, $n = p_1^{e_1} p_2^{e_2} \cdots p_k^{e_k}$, where $p_i$ are primes and $e_i$ are their corresponding exponents, then $n$ can be expressed as the sum of two squares if and only if all prime factors $p_i$ of the form $4k + 3$ have even exponents $e_i$.

More formally, if $p_i$ is a prime of the form $4k + 3$, then for each such $p_i$, $e_i$ must be even.

For example:

- The number $13$ is a prime and $13 \equiv 1 \pmod{4}$, so it can be expressed as the sum of two squares, i.e., $13 = 2^2 + 3^2$.
- The number $21$ can be decomposed into $3 \times 7$, where both $3$ and $7$ are prime factors of the form $4k + 3$ and their exponents are $1$ (odd), so $21$ cannot be expressed as the sum of two squares.

In summary, this theorem is very important in number theory for determining whether a number can be expressed as the sum of two squares.

The time complexity is $O(\sqrt{c})$, where $c$ is the given non-negative integer. The space complexity is $O(1)$.

<!-- tabs:start -->

#### Python3

```python
class Solution:
def judgeSquareSum(self, c: int) -> bool:
for i in range(2, int(sqrt(c)) + 1):
if c % i == 0:
exp = 0
while c % i == 0:
c //= i
exp += 1
if i % 4 == 3 and exp % 2 != 0:
return False
return c % 4 != 3
```

#### Java

```java
class Solution {
public boolean judgeSquareSum(int c) {
int n = (int) Math.sqrt(c);
for (int i = 2; i <= n; ++i) {
if (c % i == 0) {
int exp = 0;
while (c % i == 0) {
c /= i;
++exp;
}
if (i % 4 == 3 && exp % 2 != 0) {
return false;
}
}
}
return c % 4 != 3;
}
}
```

#### C++

```cpp
class Solution {
public:
bool judgeSquareSum(int c) {
int n = sqrt(c);
for (int i = 2; i <= n; ++i) {
if (c % i == 0) {
int exp = 0;
while (c % i == 0) {
c /= i;
++exp;
}
if (i % 4 == 3 && exp % 2 != 0) {
return false;
}
}
}
return c % 4 != 3;
}
};
```

#### Go

```go
func judgeSquareSum(c int) bool {
n := int(math.Sqrt(float64(c)))
for i := 2; i <= n; i++ {
if c%i == 0 {
exp := 0
for c%i == 0 {
c /= i
exp++
}
if i%4 == 3 && exp%2 != 0 {
return false
}
}
}
return c%4 != 3
}
```

#### TypeScript

```ts
function judgeSquareSum(c: number): boolean {
const n = Math.floor(Math.sqrt(c));
for (let i = 2; i <= n; ++i) {
if (c % i === 0) {
let exp = 0;
while (c % i === 0) {
c /= i;
++exp;
}
if (i % 4 === 3 && exp % 2 !== 0) {
return false;
}
}
}
return c % 4 !== 3;
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
19 changes: 19 additions & 0 deletions solution/0600-0699/0633.Sum of Square Numbers/Solution2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Solution {
public:
bool judgeSquareSum(int c) {
int n = sqrt(c);
for (int i = 2; i <= n; ++i) {
if (c % i == 0) {
int exp = 0;
while (c % i == 0) {
c /= i;
++exp;
}
if (i % 4 == 3 && exp % 2 != 0) {
return false;
}
}
}
return c % 4 != 3;
}
};
16 changes: 16 additions & 0 deletions solution/0600-0699/0633.Sum of Square Numbers/Solution2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
func judgeSquareSum(c int) bool {
n := int(math.Sqrt(float64(c)))
for i := 2; i <= n; i++ {
if c%i == 0 {
exp := 0
for c%i == 0 {
c /= i
exp++
}
if i%4 == 3 && exp%2 != 0 {
return false
}
}
}
return c%4 != 3
}
18 changes: 18 additions & 0 deletions solution/0600-0699/0633.Sum of Square Numbers/Solution2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Solution {
public boolean judgeSquareSum(int c) {
int n = (int) Math.sqrt(c);
for (int i = 2; i <= n; ++i) {
if (c % i == 0) {
int exp = 0;
while (c % i == 0) {
c /= i;
++exp;
}
if (i % 4 == 3 && exp % 2 != 0) {
return false;
}
}
}
return c % 4 != 3;
}
}
11 changes: 11 additions & 0 deletions solution/0600-0699/0633.Sum of Square Numbers/Solution2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:
def judgeSquareSum(self, c: int) -> bool:
for i in range(2, int(sqrt(c)) + 1):
if c % i == 0:
exp = 0
while c % i == 0:
c //= i
exp += 1
if i % 4 == 3 and exp % 2 != 0:
return False
return c % 4 != 3
16 changes: 16 additions & 0 deletions solution/0600-0699/0633.Sum of Square Numbers/Solution2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function judgeSquareSum(c: number): boolean {
const n = Math.floor(Math.sqrt(c));
for (let i = 2; i <= n; ++i) {
if (c % i === 0) {
let exp = 0;
while (c % i === 0) {
c /= i;
++exp;
}
if (i % 4 === 3 && exp % 2 !== 0) {
return false;
}
}
}
return c % 4 !== 3;
}