Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion leetcode/0215.Kth-Largest-Element-in-an-Array/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ You may assume k is always valid, 1 ≤ k ≤ array's length.

## 解题思路

在快排的 partition 操作中,每次 partition 操作结束都会返回一个点,这个标定点的下标和最终排序之后有序数组中这个元素所在的下标是一致的。利用这个特性,我们可以不断的划分数组区间,最终找到第 K 大的元素。执行一次 partition 操作以后,如果这个元素的下标比 K 小,那么接着就在后边的区间继续执行 partition 操作;如果这个元素的下标比 K 大,那么就在左边的区间继续执行 partition 操作;如果相等就直接输出这个下标对应的数组元素即可。
在快速选择 quickselect 的 partition 操作中,每次 partition 操作结束都会返回一个点,这个标定点的下标和最终排序之后有序数组中这个元素所在的下标是一致的。利用这个特性,我们可以不断的划分数组区间,最终找到第 K 大的元素。执行一次 partition 操作以后,如果这个元素的下标比 K 小,那么接着就在后边的区间继续执行 partition 操作;如果这个元素的下标比 K 大,那么就在左边的区间继续执行 partition 操作;如果相等就直接输出这个下标对应的数组元素即可。

Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ You may assume k is always valid, 1 ≤ k ≤ array's length.

## 解题思路

- 在快排的 partition 操作中,每次 partition 操作结束都会返回一个点,这个标定点的下标和最终排序之后有序数组中这个元素所在的下标是一致的。利用这个特性,我们可以不断的划分数组区间,最终找到第 K 大的元素。执行一次 partition 操作以后,如果这个元素的下标比 K 小,那么接着就在后边的区间继续执行 partition 操作;如果这个元素的下标比 K 大,那么就在左边的区间继续执行 partition 操作;如果相等就直接输出这个下标对应的数组元素即可。
- 快排的思路实现的算法时间复杂度为 O(n),空间复杂度为 O(logn)。由于证明过程很繁琐,所以不再这里展开讲。具体证明可以参考《算法导论》第 9 章第 2 小节。
- 在快速选择 quickselect 的 partition 操作中,每次 partition 操作结束都会返回一个点,这个标定点的下标和最终排序之后有序数组中这个元素所在的下标是一致的。利用这个特性,我们可以不断的划分数组区间,最终找到第 K 大的元素。执行一次 partition 操作以后,如果这个元素的下标比 K 小,那么接着就在后边的区间继续执行 partition 操作;如果这个元素的下标比 K 大,那么就在左边的区间继续执行 partition 操作;如果相等就直接输出这个下标对应的数组元素即可。
- 快速选择 quickselect 的思路实现的算法时间复杂度为 O(n),空间复杂度为 O(logn)。由于证明过程很繁琐,所以不再这里展开讲。具体证明可以参考《算法导论》第 9 章第 2 小节。


## 代码
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,5 @@ func longestSubstring1(s string, k int) int {
----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0394.Decode-String/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0397.Integer-Replacement/">下一页➡️</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0396.Rotate-Function/">下一页➡️</a></p>
</div>
117 changes: 117 additions & 0 deletions website/content/ChapterFour/0300~0399/0396.Rotate-Function.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# [396. Rotate Function](https://leetcode.com/problems/rotate-function/)

## 题目

You are given an integer array `nums` of length `n`.

Assume `arrk` to be an array obtained by rotating `nums` by `k` positions clock-wise. We define the **rotation function** `F` on `nums` as follow:

- `F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1]`.

Return the maximum value of `F(0), F(1), ..., F(n-1)`.

The test cases are generated so that the answer fits in a **32-bit** integer.

**Example 1:**

```c
Input: nums = [4,3,2,6]
Output: 26
Explanation:
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26.
```

**Example 2:**

```c
Input: nums = [100]
Output: 0
```

**Constraints:**

- `n == nums.length`
- `1 <= n <= 105`
- `-100 <= nums[i] <= 100`

## 题目大意

给定一个长度为`n`的整数数组`nums`,设`arrk`是数组`nums`顺时针旋转`k`个位置后的数组。

定义`nums`的旋转函数`F`为:

- `F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1]`

返回`F(0), F(1), ..., F(n-1)`中的最大值。

## 解题思路

**抽象化观察:**

```c
nums = [A0, A1, A2, A3]

sum = A0 + A1 + A2+ A3
F(0) = 0*A0 +0*A0 + 1*A1 + 2*A2 + 3*A3

F(1) = 0*A3 + 1*A0 + 2*A1 + 3*A2
= F(0) + (A0 + A1 + A2) - 3*A3
= F(0) + (sum-A3) - 3*A3
= F(0) + sum - 4*A3

F(2) = 0*A2 + 1*A3 + 2*A0 + 3*A1
= F(1) + A3 + A0 + A1 - 3*A2
= F(1) + sum - 4*A2

F(3) = 0*A1 + 1*A2 + 2*A3 + 3*A0
= F(2) + A2 + A3 + A0 - 3*A1
= F(2) + sum - 4*A1

// 记sum为nums数组中所有元素和
// 可以猜测当0 ≤ i < n时存在公式:
F(i) = F(i-1) + sum - n * A(n-i)
```

**数学归纳法证明迭代公式:**

根据题目中给定的旋转函数公式可得已知条件:

- `F(0) = 0×nums[0] + 1×nums[1] + ... + (n−1)×nums[n−1]`;

- `F(1) = 1×nums[0] + 2×nums[1] + ... + 0×nums[n-1]`。

令数组`nums`中所有元素和为`sum`,用数学归纳法验证:当`1 ≤ k < n`时,`F(k) = F(k-1) + sum - n×nums[n-k]`成立。

**归纳奠基**:证明`k=1`时命题成立。

```c
F(1) = 1×nums[0] + 2×nums[1] + ... + 0×nums[n-1]
= F(0) + sum - n×nums[n-1]
```

**归纳假设**:假设`F(k) = F(k-1) + sum - n×nums[n-k]`成立。

**归纳递推**:由归纳假设推出`F(k+1) = F(k) + sum - n×nums[n-(k+1)]`成立,则假设的递推公式成立。

```c
F(k+1) = (k+1)×nums[0] + k×nums[1] + ... + 0×nums[n-1]
= F(k) + sum - n×nums[n-(k+1)]
```

因此可以得到递推公式:

- 当`n = 0`时,`F(0) = 0×nums[0] + 1×nums[1] + ... + (n−1)×nums[n−1]`
- 当`1 ≤ k < n`时,`F(k) = F(k-1) + sum - n×nums[n-k]`成立。

循环遍历`0 ≤ k < n`,计算出不同的`F(k)`并不断更新最大值,就能求出`F(0), F(1), ..., F(n-1)`中的最大值。


----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0395.Longest-Substring-with-At-Least-K-Repeating-Characters/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0397.Integer-Replacement/">下一页➡️</a></p>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ func integerReplacement(n int) int {

----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0395.Longest-Substring-with-At-Least-K-Repeating-Characters/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0396.Rotate-Function/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0300~0399/0399.Evaluate-Division/">下一页➡️</a></p>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,5 @@ func dfs(matrix [][]int, row, col int, visited *[][]bool, height int) {
----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0416.Partition-Equal-Subset-Sum/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0421.Maximum-XOR-of-Two-Numbers-in-an-Array/">下一页➡️</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0419.Battleships-in-a-Board/">下一页➡️</a></p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# [419. Battleships in a Board](https://leetcode.com/problems/battleships-in-a-board/)

## 题目

Given an `m x n` matrix `board` where each cell is a battleship `'X'` or empty `'.'`, return the number of the **battleships** on `board`.

**Battleships** can only be placed horizontally or vertically on `board`. In other words, they can only be made of the shape `1 x k` (`1` row, `k` columns) or `k x 1` (`k` rows, `1` column), where `k` can be of any size. At least one horizontal or vertical cell separates between two battleships (i.e., there are no adjacent battleships).

**Example 1:**

![img](https://assets.leetcode.com/uploads/2021/04/10/battelship-grid.jpg)

```c
Input: board = [["X",".",".","X"],[".",".",".","X"],[".",".",".","X"]]
Output: 2
```

**Example 2:**

```c
Input: board = [["."]]
Output: 0
```

**Constraints:**

- `m == board.length`
- `n == board[i].length`
- `1 <= m, n <= 200`
- `board[i][j] is either '.' or 'X'`.

**Follow up:** Could you do it in one-pass, using only `O(1)` extra memory and without modifying the values `board`?

## 题目大意

给定一个大小为`m × n`的矩阵 称之为甲板,矩阵单元格中的`'X'`表示战舰,`'.'`表示空位。

战舰只能水平或竖直摆放在甲板上(换句话说,可以理解为联通的同一行`'X'`或同一列`'X'`只算作一个“战舰群”),任意俩个“战舰群”间都是不相邻的。返回甲板上“战舰群”的数量。

## 解题思路

题目进阶要求一次扫描算法,空间复杂度为`O(1)`,且不能修改矩阵中的值。

因为题目中给定的两个“战舰群”间至少有一个水平或垂直的空位分隔,所以可以通过枚举每个战舰的左上顶点即可统计“战舰群”的个数。

假设当前遍历到矩阵中`'X'`的位置为`(i, j)`,即 `board[i][j]='X'`。如果当前战舰属于一个新的“战舰群”,则需要满足以下条件:

- 当前位置的上方位为空,即 `board[i-1][j]='.'`;
- 当前位置的左方位为空,即 `board[i][j-1]='.'`;

统计出所有左方位和上方位为空的战舰个数,即可得到“战舰群”的数量。


----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0417.Pacific-Atlantic-Water-Flow/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0421.Maximum-XOR-of-Two-Numbers-in-an-Array/">下一页➡️</a></p>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ func findMaximumXOR1(nums []int) int {

----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0417.Pacific-Atlantic-Water-Flow/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0419.Battleships-in-a-Board/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0400~0499/0423.Reconstruct-Original-Digits-from-English/">下一页➡️</a></p>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,5 @@ func removeOuterParentheses1(S string) string {
----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1020.Number-of-Enclaves/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1025.Divisor-Game/">下一页➡️</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1022.Sum-of-Root-To-Leaf-Binary-Numbers/">下一页➡️</a></p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# [1022. Sum of Root To Leaf Binary Numbers](https://leetcode.com/problems/sum-of-root-to-leaf-binary-numbers/)

## 题目

You are given the root of a binary tree where each node has a value 0 or 1. Each root-to-leaf path represents a binary number starting with the most significant bit.

For example, if the path is 0 -> 1 -> 1 -> 0 -> 1, then this could represent 01101 in binary, which is 13.
For all leaves in the tree, consider the numbers represented by the path from the root to that leaf. Return the sum of these numbers.

The test cases are generated so that the answer fits in a 32-bits integer.

**Example 1:**

```c
Input: root = [1,0,1,0,1,0,1]
Output: 22
Explanation: (100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22
```

**Example 2:**

```c
Input: root = [0]
Output: 0
```

**Constraints:**

- The number of nodes in the tree is in the range `[1, 1000]`.

- `Node.val` is `0` or `1`.


## 题目大意

给定一棵结点值都是`0`或`1`的二叉树,每条从根结点到叶结点的路径都代表一个从最高有效位开始的二进制数。

返回从根节点到所有叶结点的路径所表示的数字之和。


## 解题思路

采用递归的方式对根结点`root`进行后序遍历(左子树-右子树-根结点)。

**递归函数的返回值**:

递归遍历每个结点时,计算从根结点到当前访问结点的所表示数值`sum`都用到了上次的计算结果,所以递归函数的返回值是当前访问结点的计算结果值。

**递归函数的逻辑**:

- 当前遍历结点为`nil`,表示本层递归结束了,直接`return 0`。

- 如果当前访问结点是叶结点,则返回从根结点到该结点所表示的数值`sum`。
- 如果当前访问结点不是叶结点,则返回左子树和右子树所对应的结果之和。


----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1021.Remove-Outermost-Parentheses/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1025.Divisor-Game/">下一页➡️</a></p>
</div>
2 changes: 1 addition & 1 deletion website/content/ChapterFour/1000~1099/1025.Divisor-Game.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ func divisorGame(N int) bool {

----------------------------------------------
<div style="display: flex;justify-content: space-between;align-items: center;">
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1021.Remove-Outermost-Parentheses/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1022.Sum-of-Root-To-Leaf-Binary-Numbers/">⬅️上一页</a></p>
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1000~1099/1026.Maximum-Difference-Between-Node-and-Ancestor/">下一页➡️</a></p>
</div>
Loading