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
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,13 @@ tags:

<!-- solution:start -->

### 方法一:自定义排序
### 方法一:排序

时间复杂度 $O(2nlogn)$。
我们首先对数组 $\textit{arr}$ 进行排序,然后找到数组的中位数 $m$。

接下来,我们按照题目描述的规则对数组进行排序,最后返回数组的前 $k$ 个元素即可。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{arr}$ 的长度。

<!-- tabs:start -->

Expand Down Expand Up @@ -174,6 +178,16 @@ func abs(x int) int {
}
```

#### TypeScript

```ts
function getStrongest(arr: number[], k: number): number[] {
arr.sort((a, b) => a - b);
const m = arr[(arr.length - 1) >> 1];
return arr.sort((a, b) => Math.abs(b - m) - Math.abs(a - m) || b - a).slice(0, k);
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ Any permutation of [11,8,6,6,7] is <strong>accepted</strong>.

<!-- solution:start -->

### Solution 1
### Solution 1: Sorting

We first sort the array $\textit{arr}$ and then find the median $m$ of the array.

Next, we sort the array according to the rules described in the problem, and finally return the first $k$ elements of the array.

The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{arr}$.

<!-- tabs:start -->

Expand Down Expand Up @@ -158,6 +164,16 @@ func abs(x int) int {
}
```

#### TypeScript

```ts
function getStrongest(arr: number[], k: number): number[] {
arr.sort((a, b) => a - b);
const m = arr[(arr.length - 1) >> 1];
return arr.sort((a, b) => Math.abs(b - m) - Math.abs(a - m) || b - a).slice(0, k);
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function getStrongest(arr: number[], k: number): number[] {
arr.sort((a, b) => a - b);
const m = arr[(arr.length - 1) >> 1];
return arr.sort((a, b) => Math.abs(b - m) - Math.abs(a - m) || b - a).slice(0, k);
}
12 changes: 10 additions & 2 deletions solution/1400-1499/1472.Design Browser History/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,17 @@ browserHistory.back(7); // 你原本在浏览 &quot;google.com

<!-- solution:start -->

### 方法一:
### 方法一:双栈

使用两个栈模拟前进与后退操作。
我们可以使用两个栈 $\textit{stk1}$ 和 $\textit{stk2}$ 分别存储浏览后退页面和前进页面。初始时 $\textit{stk1}$ 包含 $\textit{homepage}$,而 $\textit{stk2}$ 为空。

调用 $\text{visit}(url)$ 时,我们将 $\textit{url}$ 加入 $\textit{stk1}$,并清空 $\textit{stk2}$。时间复杂度 $O(1)$。

调用 $\text{back}(steps)$ 时,我们将 $\textit{stk1}$ 的栈顶元素弹出并加入 $\textit{stk2}$,重复这一操作 $steps$ 次,直到 $\textit{stk1}$ 的长度为 $1$ 或者 $steps$ 为 $0$。最后返回 $\textit{stk1}$ 的栈顶元素。时间复杂度 $O(\textit{steps})$。

调用 $\text{forward}(steps)$ 时,我们将 $\textit{stk2}$ 的栈顶元素弹出并加入 $\textit{stk1}$,重复这一操作 $steps$ 次,直到 $\textit{stk2}$ 为空或者 $steps$ 为 $0$。最后返回 $\textit{stk1}$ 的栈顶元素。时间复杂度 $O(\textit{steps})$。

空间复杂度 $O(n)$,其中 $n$ 是浏览历史记录的长度。

<!-- tabs:start -->

Expand Down
12 changes: 11 additions & 1 deletion solution/1400-1499/1472.Design Browser History/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,17 @@ browserHistory.back(7); // You are in &quot;google.com&quot;,

<!-- solution:start -->

### Solution 1
### Solution 1: Two Stacks

We can use two stacks, $\textit{stk1}$ and $\textit{stk2}$, to store the back and forward pages, respectively. Initially, $\textit{stk1}$ contains the $\textit{homepage}$, and $\textit{stk2}$ is empty.

When calling $\text{visit}(url)$, we add $\textit{url}$ to $\textit{stk1}$ and clear $\textit{stk2}$. The time complexity is $O(1)$.

When calling $\text{back}(steps)$, we pop the top element from $\textit{stk1}$ and push it to $\textit{stk2}$. We repeat this operation $steps$ times until the length of $\textit{stk1}$ is $1$ or $steps$ is $0$. Finally, we return the top element of $\textit{stk1}$. The time complexity is $O(\textit{steps})$.

When calling $\text{forward}(steps)$, we pop the top element from $\textit{stk2}$ and push it to $\textit{stk1}$. We repeat this operation $steps$ times until $\textit{stk2}$ is empty or $steps$ is $0$. Finally, we return the top element of $\textit{stk1}$. The time complexity is $O(\textit{steps})$.

The space complexity is $O(n)$, where $n$ is the length of the browsing history.

<!-- tabs:start -->

Expand Down
12 changes: 6 additions & 6 deletions solution/1400-1499/1473.Paint House III/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,25 +91,25 @@ tags:

### 方法一:动态规划

我们定义 $f[i][j][k]$ 表示将下标 $[0,..i]$ 的房子涂上颜色,最后一个房子的颜色为 $j$,且恰好形成 $k$ 个街区的最小花费。那么答案就是 $f[m-1][j][target]$,其中 $j$ 的取值范围为 $[1,..n]$。初始时,我们判断下标为 $0$ 的房子是否已经涂色,如果未涂色,那么 $f[0][j][1] = cost[0][j - 1]$,其中 $j \in [1,..n]$。如果已经涂色,那么 $f[0][houses[0]][1] = 0$。其他的 $f[i][j][k]$ 的值都初始化为 $\infty$。
我们定义 $f[i][j][k]$ 表示将下标 $[0,..i]$ 的房子涂上颜色,最后一个房子的颜色为 $j$,且恰好形成 $k$ 个街区的最小花费。那么答案就是 $f[m-1][j][\textit{target}]$,其中 $j$ 的取值范围为 $[1,..n]$。初始时,我们判断下标为 $0$ 的房子是否已经涂色,如果未涂色,那么 $f[0][j][1] = \textit{cost}[0][j - 1]$,其中 $j \in [1,..n]$。如果已经涂色,那么 $f[0][\textit{houses}[0]][1] = 0$。其他的 $f[i][j][k]$ 的值都初始化为 $\infty$。

接下来,我们从下标 $i=1$ 开始遍历,对于每个 $i$,我们判断下标为 $i$ 的房子是否已经涂色:

如果未涂色,那么我们可以将下标为 $i$ 的房子涂成颜色 $j$,我们枚举街区的数量 $k$,其中 $k \in [1,..min(target, i + 1)]$,并且枚举下标为 $i$ 的房子的前一个房子的颜色 $j_0$,其中 $j_0 \in [1,..n]$,那么我们可以得到状态转移方程:
如果未涂色,那么我们可以将下标为 $i$ 的房子涂成颜色 $j$,我们枚举街区的数量 $k$,其中 $k \in [1,..\min(\textit{target}, i + 1)]$,并且枚举下标为 $i$ 的房子的前一个房子的颜色 $j_0$,其中 $j_0 \in [1,..n]$,那么我们可以得到状态转移方程:

$$
f[i][j][k] = \min_{j_0 \in [1,..n]} \{ f[i - 1][j_0][k - (j \neq j_0)] + cost[i][j - 1] \}
f[i][j][k] = \min_{j_0 \in [1,..n]} \{ f[i - 1][j_0][k - (j \neq j_0)] + \textit{cost}[i][j - 1] \}
$$

如果已经涂色,那么我们可以将下标为 $i$ 的房子涂成颜色 $j$,我们枚举街区的数量 $k$,其中 $k \in [1,..min(target, i + 1)]$,并且枚举下标为 $i$ 的房子的前一个房子的颜色 $j_0$,其中 $j_0 \in [1,..n]$,那么我们可以得到状态转移方程:
如果已经涂色,那么我们可以将下标为 $i$ 的房子涂成颜色 $j$,我们枚举街区的数量 $k$,其中 $k \in [1,..\min(\textit{target}, i + 1)]$,并且枚举下标为 $i$ 的房子的前一个房子的颜色 $j_0$,其中 $j_0 \in [1,..n]$,那么我们可以得到状态转移方程:

$$
f[i][j][k] = \min_{j_0 \in [1,..n]} \{ f[i - 1][j_0][k - (j \neq j_0)] \}
$$

最后,我们返回 $f[m - 1][j][target]$,其中 $j \in [1,..n]$,如果所有的 $f[m - 1][j][target]$ 的值都为 $\infty$,那么返回 $-1$。
最后,我们返回 $f[m - 1][j][\textit{target}]$,其中 $j \in [1,..n]$,如果所有的 $f[m - 1][j][\textit{target}]$ 的值都为 $\infty$,那么返回 $-1$。

时间复杂度 $O(m \times n^2 \times target)$,空间复杂度 $O(m \times n \times target)$。其中 $m$, $n$, $target$ 分别为房子的数量,颜色的数量,街区的数量。
时间复杂度 $O(m \times n^2 \times \textit{target})$,空间复杂度 $O(m \times n \times \textit{target})$。其中 $m$, $n$, $\textit{target}$ 分别为房子的数量,颜色的数量,街区的数量。

<!-- tabs:start -->

Expand Down
24 changes: 22 additions & 2 deletions solution/1400-1499/1473.Paint House III/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Cost of paint all houses (1 + 1 + 1 + 1 + 5) = 9.
<strong>Input:</strong> houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
<strong>Output:</strong> 11
<strong>Explanation:</strong> Some houses are already painted, Paint the houses of this way [2,2,1,2,2]
This array contains target = 3 neighborhoods, [{2,2}, {1}, {2,2}].
This array contains target = 3 neighborhoods, [{2,2}, {1}, {2,2}].
Cost of paint the first and last house (10 + 1) = 11.
</pre>

Expand Down Expand Up @@ -84,7 +84,27 @@ Cost of paint the first and last house (10 + 1) = 11.

<!-- solution:start -->

### Solution 1
### Solution 1: Dynamic Programming

We define $f[i][j][k]$ to represent the minimum cost to paint houses from index $0$ to $i$, with the last house painted in color $j$, and exactly forming $k$ blocks. The answer is $f[m-1][j][\textit{target}]$, where $j$ ranges from $1$ to $n$. Initially, we check if the house at index $0$ is already painted. If it is not painted, then $f[0][j][1] = \textit{cost}[0][j - 1]$, where $j \in [1,..n]$. If it is already painted, then $f[0][\textit{houses}[0]][1] = 0$. All other values of $f[i][j][k]$ are initialized to $\infty$.

Next, we start iterating from index $i=1$. For each $i$, we check if the house at index $i$ is already painted:

If it is not painted, we can paint the house at index $i$ with color $j$. We enumerate the number of blocks $k$, where $k \in [1,..\min(\textit{target}, i + 1)]$, and enumerate the color of the previous house $j_0$, where $j_0 \in [1,..n]$. Then we can derive the state transition equation:

$$
f[i][j][k] = \min_{j_0 \in [1,..n]} \{ f[i - 1][j_0][k - (j \neq j_0)] + \textit{cost}[i][j - 1] \}
$$

If it is already painted, we can paint the house at index $i$ with color $j$. We enumerate the number of blocks $k$, where $k \in [1,..\min(\textit{target}, i + 1)]$, and enumerate the color of the previous house $j_0$, where $j_0 \in [1,..n]$. Then we can derive the state transition equation:

$$
f[i][j][k] = \min_{j_0 \in [1,..n]} \{ f[i - 1][j_0][k - (j \neq j_0)] \}
$$

Finally, we return $f[m - 1][j][\textit{target}]$, where $j \in [1,..n]$. If all values of $f[m - 1][j][\textit{target}]$ are $\infty$, then return $-1$.

The time complexity is $O(m \times n^2 \times \textit{target})$, and the space complexity is $O(m \times n \times \textit{target})$. Here, $m$, $n$, and $\textit{target}$ represent the number of houses, the number of colors, and the number of blocks, respectively.

<!-- tabs:start -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ tags:

### 方法一:模拟

按照题意模拟,遍历链表,每次遍历 $m$ 个节点,然后删除 $n$ 个节点,直到链表尾部
我们可以模拟整个删除过程,首先用 $\textit{pre}$ 指针指向链表头部,然后遍历链表,移动 $m - 1$ 步,如果 $\textit{pre}$ 为空,说明从当前节点开始的节点个数小于 $m$,直接返回头部;否则,用 $\textit{cur}$ 指针指向 $\textit{pre}$,然后移动 $n$ 步,如果 $\textit{cur}$ 为空,说明从 $\textit{pre}$ 开始的节点个数小于 $m + n$,直接将 $\textit{pre}$ 的 $\textit{next}$ 指向 $\text{null}$;否则,将 $\textit{pre}$ 的 $\textit{next}$ 指向 $\textit{cur}$ 的 $\textit{next}$,然后将 $\textit{pre}$ 移动到 $\textit{pre}$ 的 $\textit{next}$。继续遍历链表,直到 $\textit{pre}$ 为空,返回头部

时间复杂度 $O(n)$,空间复杂度 $O(1)$。
时间复杂度 $O(n)$,其中 $n$ 是链表中节点的个数。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand Down Expand Up @@ -222,6 +222,41 @@ func deleteNodes(head *ListNode, m int, n int) *ListNode {
}
```

#### TypeScript

```ts
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/

function deleteNodes(head: ListNode | null, m: number, n: number): ListNode | null {
let pre = head;
while (pre) {
for (let i = 0; i < m - 1 && pre; ++i) {
pre = pre.next;
}
if (!pre) {
break;
}
let cur = pre;
for (let i = 0; i < n && cur; ++i) {
cur = cur.next;
}
pre.next = cur?.next || null;
pre = pre.next;
}
return head;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ Head of the linked list after removing nodes is returned.

<!-- solution:start -->

### Solution 1
### Solution 1: Simulation

We can simulate the entire deletion process. First, use a pointer $\textit{pre}$ to point to the head of the linked list, then traverse the linked list, moving $m - 1$ steps. If $\textit{pre}$ is null, it means the number of nodes from the current node is less than $m$, so we directly return the head. Otherwise, use a pointer $\textit{cur}$ to point to $\textit{pre}$, then move $n$ steps. If $\textit{cur}$ is null, it means the number of nodes from $\textit{pre}$ is less than $m + n$, so we directly set the $\textit{next}$ of $\textit{pre}$ to null. Otherwise, set the $\textit{next}$ of $\textit{pre}$ to the $\textit{next}$ of $\textit{cur}$, then move $\textit{pre}$ to its $\textit{next}$. Continue traversing the linked list until $\textit{pre}$ is null, then return the head.

The time complexity is $O(n)$, where $n$ is the number of nodes in the linked list. The space complexity is $O(1)$.

<!-- tabs:start -->

Expand Down Expand Up @@ -201,6 +205,41 @@ func deleteNodes(head *ListNode, m int, n int) *ListNode {
}
```

#### TypeScript

```ts
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/

function deleteNodes(head: ListNode | null, m: number, n: number): ListNode | null {
let pre = head;
while (pre) {
for (let i = 0; i < m - 1 && pre; ++i) {
pre = pre.next;
}
if (!pre) {
break;
}
let cur = pre;
for (let i = 0; i < n && cur; ++i) {
cur = cur.next;
}
pre.next = cur?.next || null;
pre = pre.next;
}
return head;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/

function deleteNodes(head: ListNode | null, m: number, n: number): ListNode | null {
let pre = head;
while (pre) {
for (let i = 0; i < m - 1 && pre; ++i) {
pre = pre.next;
}
if (!pre) {
break;
}
let cur = pre;
for (let i = 0; i < n && cur; ++i) {
cur = cur.next;
}
pre.next = cur?.next || null;
pre = pre.next;
}
return head;
}
Loading
Loading