Skip to content

Commit

Permalink
add new problem
Browse files Browse the repository at this point in the history
  • Loading branch information
wujunwei committed Jun 13, 2023
1 parent 773a0cc commit 1e2a1ac
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 25 deletions.
40 changes: 20 additions & 20 deletions content/bit/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ theme="serif"

### 基础知识

|符号|描述|运算规则|
|:----:|:----:|:----:|
|&||两个位都为1时,结果才为1|
|\|||两个位都为0时,结果才为0|
|^|异或|两个位相同为0,相异为1|
|~|取反|0变1,1变0|
|<<|左移|各二进位全部左移若干位,高位丢弃,低位补0|
|>>|右移|各二进位全部右移若干位|
| 符号 | 描述 | 运算规则 |
|:--:|:--:|:---------------------:|
| & || 两个位都为1时,结果才为1 |
| \| || 两个位都为0时,结果才为0 |
| ^ | 异或 | 两个位相同为0,相异为1 |
| ~ | 取反 | 0变1,1变0 |
| << | 左移 | 各二进位全部左移若干位,高位丢弃,低位补0 |
| >> | 右移 | 各二进位全部右移若干位 |

---

Expand Down Expand Up @@ -48,18 +48,18 @@ int reversal(int a) {
```
---
|功能|示例|位运算|
|:----:|:----:|:----:|
| 把右数第k位变成1| (101001->101101,k=3)| x \| (1 << (k-1)) |
| 把右数第k位变成0| (101101->101001,k=3)| x & ~ (1 << (k-1)) |
| 右数第k位取反| (101001->101101,k=3)| x ^ (1 << (k-1)) |
| 取末三位| (1101101->101)| x & 7 |
| 取末k位| (1101101->1101,k=5)| x & (1 << k-1) |
| 把右边连续的1变成0| (100101111->100100000)| x & (x+1) |
| 把右起第一个0变成1| (100101111->100111111)| x \| (x+1) |
| 把右边连续的0变成1| (11011000->11011111)| x \| (x-1) |
| 取右边连续的1| (100101111->1111)| (x ^ (x+1)) >> 1 |
| 把右起第一个1变成0| (100101000->100100000)| x ^ (x-1) |
| 功能 | 示例 | 位运算 |
|:----------:|:----------------------:|:------------------:|
| 把右数第k位变成1 | (101001->101101,k=3) | x \| (1 << (k-1)) |
| 把右数第k位变成0 | (101101->101001,k=3) | x & ~ (1 << (k-1)) |
| 右数第k位取反 | (101001->101101,k=3) | x ^ (1 << (k-1)) |
| 取末三位 | (1101101->101) | x & 7 |
| 取末k位 | (1101101->1101,k=5) | x & (1 << k-1) |
| 把右边连续的1变成0 | (100101111->100100000) | x & (x+1) |
| 把右起第一个0变成1 | (100101111->100111111) | x \| (x+1) |
| 把右边连续的0变成1 | (11011000->11011111) | x \| (x-1) |
| 取右边连续的1 | (100101111->1111) | (x ^ (x+1)) >> 1 |
| 把右起第一个1变成0 | (100101000->100100000) | x ^ (x-1) |
{{% /section %}}
Expand Down
109 changes: 104 additions & 5 deletions content/math/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,16 +201,115 @@ func fib(n int) int {

---

### answer 5
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

提示: 1 <= n <= 10000


```
输入:n = 12
输出:3
解释:12 = 4 + 4 + 4
```
```
输入:n = 13
输出:2
解释:13 = 4 + 9
```
---

#### 方法一:动态规划

{{% section %}}

$f[i]$ 表示最少需要多少个数的平方来表示整数 $i$。
这些数必然落在区间 $[1,\\sqrt{n}]$。
$$
f[i]=1+\\min_{j=1}^{\\lfloor\\sqrt{i}\\rfloor}{f[i-j^2]}
$$

---

**复杂度分析**

- 时间复杂度:$O(n\\sqrt{n})$,其中 $n$ 为给定的正整数。
- 空间复杂度:$O(n)$。我们需要 $O(n)$ 的空间保存状态。
---

```go
package main
func fib(n int) {
nums := [30]int{1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040};
return nums[n-1];
func numSquares(n int) int {
f := make([]int, n+1)
for i := 1; i <= n; i++ {
minn := math.MaxInt32
for j := 1; j*j <= i; j++ {
minn = min(minn, f[i-j*j])
}
f[i] = minn + 1
}
return f[n]
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
```

{{% /section %}}

---

#### 方法二:数学

{{% section %}}

`拉格朗日四平方和定理`: 任意一个正整数都可以被表示为至多四个正整数的平方和。 同时四平方和定理包含了一个更强的结论:当且仅当 $n = 4^k \\times (8m+7)$ 时,$n$ 可以被表示为至多三个正整数的平方和。因此,当 $n = 4^k \\times (8m+7)$ 时,$n$ 只能被表示为四个正整数的平方和。

---

[//]: # (当 $n ≠ 4^k \\times &#40;8m+7&#41;$ 时,我们需要判断到底多少个完全平方数能够表示 $n$,我们知道答案只会是 $1,2,3$ 中的一个:)
- $1$ :则必有 $n$ 为完全平方数,这很好判断;
- $2$ :则有 $n=a^2+b^2$,我们只需要枚举所有的 $a(1 \\leq a \\leq \\sqrt{n})$,判断 $n-a^2$ 是否为完全平方数即可;
- $3$ :我们很难在一个优秀的时间复杂度内解决它,但我们只需要检查答案为 $1$ 或 $2$ 的两种情况,即可利用排除法确定答案。

---

```go [Golang]
// 判断是否为完全平方数
func isPerfectSquare(x int) bool {
y := int(math.Sqrt(float64(x)))
return y*y == x
}
// 判断是否能表示为 4^k*(8m+7)
func checkAnswer4(x int) bool {
for x%4 == 0 {
x /= 4
}
return x%8 == 7
}
func numSquares(n int) int {
if isPerfectSquare(n) {
return 1
}
if checkAnswer4(n) {
return 4
}
for i := 1; i*i <= n; i++ {
j := n - i*i
if isPerfectSquare(j) {
return 2
}
}
return 3
}
```

- 时间复杂度:$O(\\sqrt{n})$
- 空间复杂度:$O(1)$

{{% /section %}}

---

#### [下一节](/#/8)
Expand Down
4 changes: 4 additions & 0 deletions content/others/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ func majorityElement(nums []int) int {
}
```

---



---

[更多算法](https://www.processon.com/view/link/5ff6ab75f346fb340dedc38c)
Expand Down

0 comments on commit 1e2a1ac

Please sign in to comment.