diff --git a/solution/0300-0399/0367.Valid Perfect Square/README.md b/solution/0300-0399/0367.Valid Perfect Square/README.md index fbb0841074883..f87fa7edbc0ac 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/README.md +++ b/solution/0300-0399/0367.Valid Perfect Square/README.md @@ -57,9 +57,9 @@ tags: ### 方法一:二分查找 -不断循环二分枚举数字,判断该数的平方与 `num` 的大小关系,进而缩短空间,继续循环直至 $left \lt right$ 不成立。循环结束判断 $left^2$ 与 `num` 是否相等。 +我们可以使用二分查找来解决这个问题。定义二分查找的左边界 $l = 1$,右边界 $r = num$,然后在 $[l, r]$ 的范围内查找满足 $x^2 \geq num$ 的最小整数 $x$。最后,如果 $x^2 = num$,则说明 $num$ 是一个完全平方数。 -时间复杂度:$O(logN)$。 +时间复杂度 $O(\log n)$,其中 $n$ 是给定的数字。空间复杂度 $O(1)$。 @@ -68,14 +68,8 @@ tags: ```python class Solution: def isPerfectSquare(self, num: int) -> bool: - left, right = 1, num - while left < right: - mid = (left + right) >> 1 - if mid * mid >= num: - right = mid - else: - left = mid + 1 - return left * left == num + l = bisect_left(range(1, num + 1), num, key=lambda x: x * x) + 1 + return l * l == num ``` #### Java @@ -83,16 +77,16 @@ class Solution: ```java class Solution { public boolean isPerfectSquare(int num) { - long left = 1, right = num; - while (left < right) { - long mid = (left + right) >>> 1; - if (mid * mid >= num) { - right = mid; + int l = 1, r = num; + while (l < r) { + int mid = (l + r) >>> 1; + if (1L * mid * mid >= num) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left * left == num; + return l * l == num; } } ``` @@ -103,15 +97,16 @@ class Solution { class Solution { public: bool isPerfectSquare(int num) { - long left = 1, right = num; - while (left < right) { - long mid = left + right >> 1; - if (mid * mid >= num) - right = mid; - else - left = mid + 1; + int l = 1, r = num; + while (l < r) { + int mid = l + (r - l) / 2; + if (1LL * mid * mid >= num) { + r = mid; + } else { + l = mid + 1; + } } - return left * left == num; + return 1LL * l * l == num; } }; ``` @@ -120,16 +115,8 @@ public: ```go func isPerfectSquare(num int) bool { - left, right := 1, num - for left < right { - mid := (left + right) >> 1 - if mid*mid >= num { - right = mid - } else { - left = mid + 1 - } - } - return left*left == num + l := sort.Search(num, func(i int) bool { return i*i >= num }) + return l*l == num } ``` @@ -137,44 +124,35 @@ func isPerfectSquare(num int) bool { ```ts function isPerfectSquare(num: number): boolean { - let left = 1; - let right = num >> 1; - while (left < right) { - const mid = (left + right) >>> 1; - if (mid * mid < num) { - left = mid + 1; + let [l, r] = [1, num]; + while (l < r) { + const mid = (l + r) >> 1; + if (mid >= num / mid) { + r = mid; } else { - right = mid; + l = mid + 1; } } - return left * left === num; + return l * l === num; } ``` #### Rust ```rust -use std::cmp::Ordering; impl Solution { pub fn is_perfect_square(num: i32) -> bool { - let num: i64 = num as i64; - let mut left = 1; - let mut right = num >> 1; - while left < right { - let mid = left + (right - left) / 2; - match (mid * mid).cmp(&num) { - Ordering::Less => { - left = mid + 1; - } - Ordering::Greater => { - right = mid - 1; - } - Ordering::Equal => { - return true; - } + let mut l = 1; + let mut r = num as i64; + while l < r { + let mid = (l + r) / 2; + if mid * mid >= (num as i64) { + r = mid; + } else { + l = mid + 1; } } - left * left == num + l * l == (num as i64) } } ``` @@ -185,11 +163,11 @@ impl Solution { -### 方法二:转换为数学问题 +### 方法二:数学 -由于 `n² = 1 + 3 + 5 + ... + (2n-1)`,对数字 `num` 不断减去 $i$ (`i = 1, 3, 5, ...`) 直至 `num` 不大于 0,如果最终 `num` 等于 0,说明是一个有效的完全平方数。 +由于 $1 + 3 + 5 + \cdots + (2n - 1) = n^2$,我们可以将 $num$ 逐渐减去 $1, 3, 5, \cdots$,如果最后 $num = 0$,则说明 $num$ 是一个完全平方数。 -时间复杂度:$O(sqrt(N))$。 +时间复杂度 $O(\sqrt n)$,空间复杂度 $O(1)$。 @@ -224,7 +202,9 @@ class Solution { class Solution { public: bool isPerfectSquare(int num) { - for (int i = 1; num > 0; i += 2) num -= i; + for (int i = 1; num > 0; i += 2) { + num -= i; + } return num == 0; } }; diff --git a/solution/0300-0399/0367.Valid Perfect Square/README_EN.md b/solution/0300-0399/0367.Valid Perfect Square/README_EN.md index e45e691062d37..f7f654a93ce80 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/README_EN.md +++ b/solution/0300-0399/0367.Valid Perfect Square/README_EN.md @@ -53,7 +53,11 @@ tags: -### Solution 1: Binary search +### Solution 1: Binary Search + +We can use binary search to solve this problem. Define the left boundary $l = 1$ and the right boundary $r = num$ of the binary search, then find the smallest integer $x$ that satisfies $x^2 \geq num$ in the range $[l, r]$. Finally, if $x^2 = num$, then $num$ is a perfect square. + +The time complexity is $O(\log n)$, where $n$ is the given number. The space complexity is $O(1)$. @@ -62,14 +66,8 @@ tags: ```python class Solution: def isPerfectSquare(self, num: int) -> bool: - left, right = 1, num - while left < right: - mid = (left + right) >> 1 - if mid * mid >= num: - right = mid - else: - left = mid + 1 - return left * left == num + l = bisect_left(range(1, num + 1), num, key=lambda x: x * x) + 1 + return l * l == num ``` #### Java @@ -77,16 +75,16 @@ class Solution: ```java class Solution { public boolean isPerfectSquare(int num) { - long left = 1, right = num; - while (left < right) { - long mid = (left + right) >>> 1; - if (mid * mid >= num) { - right = mid; + int l = 1, r = num; + while (l < r) { + int mid = (l + r) >>> 1; + if (1L * mid * mid >= num) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left * left == num; + return l * l == num; } } ``` @@ -97,15 +95,16 @@ class Solution { class Solution { public: bool isPerfectSquare(int num) { - long left = 1, right = num; - while (left < right) { - long mid = left + right >> 1; - if (mid * mid >= num) - right = mid; - else - left = mid + 1; + int l = 1, r = num; + while (l < r) { + int mid = l + (r - l) / 2; + if (1LL * mid * mid >= num) { + r = mid; + } else { + l = mid + 1; + } } - return left * left == num; + return 1LL * l * l == num; } }; ``` @@ -114,16 +113,8 @@ public: ```go func isPerfectSquare(num int) bool { - left, right := 1, num - for left < right { - mid := (left + right) >> 1 - if mid*mid >= num { - right = mid - } else { - left = mid + 1 - } - } - return left*left == num + l := sort.Search(num, func(i int) bool { return i*i >= num }) + return l*l == num } ``` @@ -131,44 +122,35 @@ func isPerfectSquare(num int) bool { ```ts function isPerfectSquare(num: number): boolean { - let left = 1; - let right = num >> 1; - while (left < right) { - const mid = (left + right) >>> 1; - if (mid * mid < num) { - left = mid + 1; + let [l, r] = [1, num]; + while (l < r) { + const mid = (l + r) >> 1; + if (mid >= num / mid) { + r = mid; } else { - right = mid; + l = mid + 1; } } - return left * left === num; + return l * l === num; } ``` #### Rust ```rust -use std::cmp::Ordering; impl Solution { pub fn is_perfect_square(num: i32) -> bool { - let num: i64 = num as i64; - let mut left = 1; - let mut right = num >> 1; - while left < right { - let mid = left + (right - left) / 2; - match (mid * mid).cmp(&num) { - Ordering::Less => { - left = mid + 1; - } - Ordering::Greater => { - right = mid - 1; - } - Ordering::Equal => { - return true; - } + let mut l = 1; + let mut r = num as i64; + while l < r { + let mid = (l + r) / 2; + if mid * mid >= (num as i64) { + r = mid; + } else { + l = mid + 1; } } - left * left == num + l * l == (num as i64) } } ``` @@ -179,20 +161,11 @@ impl Solution { -### Solution 2: Math trick +### Solution 2: Mathematics -This is a math problem: +Since $1 + 3 + 5 + \cdots + (2n - 1) = n^2$, we can gradually subtract $1, 3, 5, \cdots$ from $num$. If $num$ finally equals $0$, then $num$ is a perfect square. -```bash -1 = 1 -4 = 1 + 3 -9 = 1 + 3 + 5 -16 = 1 + 3 + 5 + 7 -25 = 1 + 3 + 5 + 7 + 9 -36 = 1 + 3 + 5 + 7 + 9 + 11 -.... -so 1+3+...+(2n-1) = (2n-1 + 1)n/2 = n² -``` +The time complexity is $O(\sqrt n)$, and the space complexity is $O(1)$. @@ -227,7 +200,9 @@ class Solution { class Solution { public: bool isPerfectSquare(int num) { - for (int i = 1; num > 0; i += 2) num -= i; + for (int i = 1; num > 0; i += 2) { + num -= i; + } return num == 0; } }; diff --git a/solution/0300-0399/0367.Valid Perfect Square/Solution.cpp b/solution/0300-0399/0367.Valid Perfect Square/Solution.cpp index 07f694c111408..c159ba5e8847b 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/Solution.cpp +++ b/solution/0300-0399/0367.Valid Perfect Square/Solution.cpp @@ -1,14 +1,15 @@ class Solution { public: bool isPerfectSquare(int num) { - long left = 1, right = num; - while (left < right) { - long mid = left + right >> 1; - if (mid * mid >= num) - right = mid; - else - left = mid + 1; + int l = 1, r = num; + while (l < r) { + int mid = l + (r - l) / 2; + if (1LL * mid * mid >= num) { + r = mid; + } else { + l = mid + 1; + } } - return left * left == num; + return 1LL * l * l == num; } }; \ No newline at end of file diff --git a/solution/0300-0399/0367.Valid Perfect Square/Solution.go b/solution/0300-0399/0367.Valid Perfect Square/Solution.go index 1a3d8aad3bace..b7b49276b8b3c 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/Solution.go +++ b/solution/0300-0399/0367.Valid Perfect Square/Solution.go @@ -1,12 +1,4 @@ func isPerfectSquare(num int) bool { - left, right := 1, num - for left < right { - mid := (left + right) >> 1 - if mid*mid >= num { - right = mid - } else { - left = mid + 1 - } - } - return left*left == num + l := sort.Search(num, func(i int) bool { return i*i >= num }) + return l*l == num } \ No newline at end of file diff --git a/solution/0300-0399/0367.Valid Perfect Square/Solution.java b/solution/0300-0399/0367.Valid Perfect Square/Solution.java index 994183c6ddaf6..434fd52a0c2c9 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/Solution.java +++ b/solution/0300-0399/0367.Valid Perfect Square/Solution.java @@ -1,14 +1,14 @@ class Solution { public boolean isPerfectSquare(int num) { - long left = 1, right = num; - while (left < right) { - long mid = (left + right) >>> 1; - if (mid * mid >= num) { - right = mid; + int l = 1, r = num; + while (l < r) { + int mid = (l + r) >>> 1; + if (1L * mid * mid >= num) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left * left == num; + return l * l == num; } } \ No newline at end of file diff --git a/solution/0300-0399/0367.Valid Perfect Square/Solution.py b/solution/0300-0399/0367.Valid Perfect Square/Solution.py index 04caeac2f51a1..2fe751e948fb3 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/Solution.py +++ b/solution/0300-0399/0367.Valid Perfect Square/Solution.py @@ -1,10 +1,4 @@ class Solution: def isPerfectSquare(self, num: int) -> bool: - left, right = 1, num - while left < right: - mid = (left + right) >> 1 - if mid * mid >= num: - right = mid - else: - left = mid + 1 - return left * left == num + l = bisect_left(range(1, num + 1), num, key=lambda x: x * x) + 1 + return l * l == num diff --git a/solution/0300-0399/0367.Valid Perfect Square/Solution.rs b/solution/0300-0399/0367.Valid Perfect Square/Solution.rs index 764668be9f320..e029c55f2dad8 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/Solution.rs +++ b/solution/0300-0399/0367.Valid Perfect Square/Solution.rs @@ -1,23 +1,15 @@ -use std::cmp::Ordering; impl Solution { pub fn is_perfect_square(num: i32) -> bool { - let num: i64 = num as i64; - let mut left = 1; - let mut right = num >> 1; - while left < right { - let mid = left + (right - left) / 2; - match (mid * mid).cmp(&num) { - Ordering::Less => { - left = mid + 1; - } - Ordering::Greater => { - right = mid - 1; - } - Ordering::Equal => { - return true; - } + let mut l = 1; + let mut r = num as i64; + while l < r { + let mid = (l + r) / 2; + if mid * mid >= (num as i64) { + r = mid; + } else { + l = mid + 1; } } - left * left == num + l * l == (num as i64) } } diff --git a/solution/0300-0399/0367.Valid Perfect Square/Solution.ts b/solution/0300-0399/0367.Valid Perfect Square/Solution.ts index e11e206fe243e..ef113ed33948b 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/Solution.ts +++ b/solution/0300-0399/0367.Valid Perfect Square/Solution.ts @@ -1,13 +1,12 @@ function isPerfectSquare(num: number): boolean { - let left = 1; - let right = num >> 1; - while (left < right) { - const mid = (left + right) >>> 1; - if (mid * mid < num) { - left = mid + 1; + let [l, r] = [1, num]; + while (l < r) { + const mid = (l + r) >> 1; + if (mid >= num / mid) { + r = mid; } else { - right = mid; + l = mid + 1; } } - return left * left === num; + return l * l === num; } diff --git a/solution/0300-0399/0367.Valid Perfect Square/Solution2.cpp b/solution/0300-0399/0367.Valid Perfect Square/Solution2.cpp index da03061abc243..d662caf94f5eb 100644 --- a/solution/0300-0399/0367.Valid Perfect Square/Solution2.cpp +++ b/solution/0300-0399/0367.Valid Perfect Square/Solution2.cpp @@ -1,7 +1,9 @@ class Solution { public: bool isPerfectSquare(int num) { - for (int i = 1; num > 0; i += 2) num -= i; + for (int i = 1; num > 0; i += 2) { + num -= i; + } return num == 0; } }; \ No newline at end of file