Skip to content

feat: add solutions to lc problem: No.1884 #3627

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 1 commit into from
Oct 9, 2024
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 @@ -65,32 +65,107 @@ tags:

<!-- solution:start -->

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

我们定义 $f[i]$ 表示有两枚鸡蛋,在 $i$ 层楼中确定 $f$ 的最小操作次数。初始时 $f[0] = 0$,其余 $f[i] = +\infty$。答案为 $f[n]$。

考虑 $f[i]$,我们可以枚举第一枚鸡蛋从第 $j$ 层楼扔下,其中 $1 \leq j \leq i$,此时有两种情况:

- 鸡蛋碎了,此时我们剩余一枚鸡蛋,需要在 $j - 1$ 层楼中确定 $f$,这需要 $j - 1$ 次操作,因此总操作次数为 $1 + (j - 1)$;
- 鸡蛋没碎,此时我们剩余两枚鸡蛋,需要在 $i - j$ 层楼中确定 $f$,这需要 $f[i - j]$ 次操作,因此总操作次数为 $1 + f[i - j]$。

综上,我们可以得到状态转移方程:

$$
f[i] = \min_{1 \leq j \leq i} \{1 + \max(j - 1, f[i - j])\}
$$

最后,我们返回 $f[n]$ 即可。

时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为楼层数。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def twoEggDrop(self, n: int) -> int:
f = [0] + [inf] * n
for i in range(1, n + 1):
for j in range(1, i + 1):
f[i] = min(f[i], 1 + max(j - 1, f[i - j]))
return f[n]
```

#### Java

```java

class Solution {
public int twoEggDrop(int n) {
int[] f = new int[n + 1];
Arrays.fill(f, 1 << 29);
f[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i] = Math.min(f[i], 1 + Math.max(j - 1, f[i - j]));
}
}
return f[n];
}
}
```

#### C++

```cpp

class Solution {
public:
int twoEggDrop(int n) {
int f[n + 1];
memset(f, 0x3f, sizeof(f));
f[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i] = min(f[i], 1 + max(j - 1, f[i - j]));
}
}
return f[n];
}
};
```

#### Go

```go
func twoEggDrop(n int) int {
f := make([]int, n+1)
for i := range f {
f[i] = 1 << 29
}
f[0] = 0
for i := 1; i <= n; i++ {
for j := 1; j <= i; j++ {
f[i] = min(f[i], 1+max(j-1, f[i-j]))
}
}
return f[n]
}
```

#### TypeScript

```ts
function twoEggDrop(n: number): number {
const f: number[] = Array(n + 1).fill(Infinity);
f[0] = 0;
for (let i = 1; i <= n; ++i) {
for (let j = 1; j <= i; ++j) {
f[i] = Math.min(f[i], 1 + Math.max(j - 1, f[i - j]));
}
}
return f[n];
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,32 +62,107 @@ Regardless of the outcome, it takes at most 14 drops to determine f.

<!-- solution:start -->

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

We define $f[i]$ to represent the minimum number of operations to determine $f$ in $i$ floors with two eggs. Initially, $f[0] = 0$, and the rest $f[i] = +\infty$. The answer is $f[n]$.

Considering $f[i]$, we can enumerate the first egg thrown from the $j$-th floor, where $1 \leq j \leq i$. At this point, there are two cases:

- The egg breaks. At this time, we have one egg left and need to determine $f$ in $j - 1$ floors, which requires $j - 1$ operations. Therefore, the total number of operations is $1 + (j - 1)$;
- The egg does not break. At this time, we have two eggs left and need to determine $f$ in $i - j$ floors, which requires $f[i - j]$ operations. Therefore, the total number of operations is $1 + f[i - j]$.

In summary, we can obtain the state transition equation:

$$
f[i] = \min_{1 \leq j \leq i} \{1 + \max(j - 1, f[i - j])\}
$$

Finally, we return $f[n]$.

The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Where $n$ is the number of floors.

<!-- tabs:start -->

#### Python3

```python

class Solution:
def twoEggDrop(self, n: int) -> int:
f = [0] + [inf] * n
for i in range(1, n + 1):
for j in range(1, i + 1):
f[i] = min(f[i], 1 + max(j - 1, f[i - j]))
return f[n]
```

#### Java

```java

class Solution {
public int twoEggDrop(int n) {
int[] f = new int[n + 1];
Arrays.fill(f, 1 << 29);
f[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i] = Math.min(f[i], 1 + Math.max(j - 1, f[i - j]));
}
}
return f[n];
}
}
```

#### C++

```cpp

class Solution {
public:
int twoEggDrop(int n) {
int f[n + 1];
memset(f, 0x3f, sizeof(f));
f[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i] = min(f[i], 1 + max(j - 1, f[i - j]));
}
}
return f[n];
}
};
```

#### Go

```go
func twoEggDrop(n int) int {
f := make([]int, n+1)
for i := range f {
f[i] = 1 << 29
}
f[0] = 0
for i := 1; i <= n; i++ {
for j := 1; j <= i; j++ {
f[i] = min(f[i], 1+max(j-1, f[i-j]))
}
}
return f[n]
}
```

#### TypeScript

```ts
function twoEggDrop(n: number): number {
const f: number[] = Array(n + 1).fill(Infinity);
f[0] = 0;
for (let i = 1; i <= n; ++i) {
for (let j = 1; j <= i; ++j) {
f[i] = Math.min(f[i], 1 + Math.max(j - 1, f[i - j]));
}
}
return f[n];
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Solution {
public:
int twoEggDrop(int n) {
int f[n + 1];
memset(f, 0x3f, sizeof(f));
f[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i] = min(f[i], 1 + max(j - 1, f[i - j]));
}
}
return f[n];
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
func twoEggDrop(n int) int {
f := make([]int, n+1)
for i := range f {
f[i] = 1 << 29
}
f[0] = 0
for i := 1; i <= n; i++ {
for j := 1; j <= i; j++ {
f[i] = min(f[i], 1+max(j-1, f[i-j]))
}
}
return f[n]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Solution {
public int twoEggDrop(int n) {
int[] f = new int[n + 1];
Arrays.fill(f, 1 << 29);
f[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i] = Math.min(f[i], 1 + Math.max(j - 1, f[i - j]));
}
}
return f[n];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Solution:
def twoEggDrop(self, n: int) -> int:
f = [0] + [inf] * n
for i in range(1, n + 1):
for j in range(1, i + 1):
f[i] = min(f[i], 1 + max(j - 1, f[i - j]))
return f[n]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function twoEggDrop(n: number): number {
const f: number[] = Array(n + 1).fill(Infinity);
f[0] = 0;
for (let i = 1; i <= n; ++i) {
for (let j = 1; j <= i; ++j) {
f[i] = Math.min(f[i], 1 + Math.max(j - 1, f[i - j]));
}
}
return f[n];
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ tags:

根据题目描述,我们需要求出数组 $\textit{nums}$ 下标 $l$ 到 $r$ 的元素的按位或运算的结果,即 $\textit{nums}[l] \lor \textit{nums}[l + 1] \lor \cdots \lor \textit{nums}[r]$。其中 $\lor$ 表示按位或运算。

如果我们每次固定右端点 $r$,那么左端点 $l$ 的范围是 $[0, r]$。每次移动右端点 $r$,按位或的结果只会变大,我们用一个变量 $s$ 记录当前的按位或的结果,如果 $s$ 大于 $k$,我们就将左端点 $l$ 向右移动,直到 $s$ 小于等于 $k$。在移动左端点 $l$ 的过程中,我们需要维护一个数组 $cnt$,记录当前区间内每个二进制位上 $0$ 的个数,当 $cnt[h]$ 为 $0$ 时,说明当前区间内的元素在第 $h$ 位上都为 $1$,我们就可以将 $s$ 的第 $h$ 位设置为 $0$。
如果我们每次固定右端点 $r$,那么左端点 $l$ 的范围是 $[0, r]$。每次移动右端点 $r$,按位或的结果只会变大,我们用一个变量 $s$ 记录当前的按位或的结果,如果 $s$ 大于 $k$,我们就将左端点 $l$ 向右移动,直到 $s$ 小于等于 $k$。在移动左端点 $l$ 的过程中,我们需要维护一个数组 $cnt$,记录当前区间内每个二进制位上 $0$ 的个数,当 $cnt[h]$ 为 $0$ 时,说明当前区间内的元素在第 $h$ 位上都为 $0$,我们就可以将 $s$ 的第 $h$ 位设置为 $0$。

时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$。其中 $n$ 和 $M$ 分别是数组 $\textit{nums}$ 的长度和数组 $\textit{nums}$ 中元素的最大值。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ tags:

According to the problem description, we need to calculate the result of the bitwise OR operation of elements from index $l$ to $r$ in the array $\textit{nums}$, that is, $\textit{nums}[l] \lor \textit{nums}[l + 1] \lor \cdots \lor \textit{nums}[r]$, where $\lor$ represents the bitwise OR operation.

If we fix the right endpoint $r$, then the range of the left endpoint $l$ is $[0, r]$. Each time we move the right endpoint $r$, the result of the bitwise OR operation will only increase. We use a variable $s$ to record the current result of the bitwise OR operation. If $s$ is greater than $k$, we move the left endpoint $l$ to the right until $s$ is less than or equal to $k$. During the process of moving the left endpoint $l$, we need to maintain an array $cnt$ to record the number of $0$s on each binary digit in the current interval. When $cnt[h] = 0$, it means that all elements in the current interval have a $1$ on the $h^{th}$ bit, and we can set the $h^{th}$ bit of $s$ to $0$.
If we fix the right endpoint $r$, then the range of the left endpoint $l$ is $[0, r]$. Each time we move the right endpoint $r$, the result of the bitwise OR operation will only increase. We use a variable $s$ to record the current result of the bitwise OR operation. If $s$ is greater than $k$, we move the left endpoint $l$ to the right until $s$ is less than or equal to $k$. During the process of moving the left endpoint $l$, we need to maintain an array $cnt$ to record the number of $0$s on each binary digit in the current interval. When $cnt[h] = 0$, it means that all elements in the current interval have a $0$ on the $h^{th}$ bit, and we can set the $h^{th}$ bit of $s$ to $0$.

The time complexity is $O(n \times \log M)$, and the space complexity is $O(\log M)$. Here, $n$ and $M$ respectively represent the length of the array $\textit{nums}$ and the maximum value in the array $\textit{nums}$.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class Solution:
def minimumAverage(self, nums: List[int]) -> float:
nums.sort()
n = len(nums)
return min(nums[i] + nums[n - i - 1] for i in range(n // 2)) / 2
return min(nums[i] + nums[-i - 1] for i in range(n // 2)) / 2
```

#### Java
Expand Down Expand Up @@ -252,6 +252,19 @@ function minimumAverage(nums: number[]): number {
}
```

#### Rust

```rust
impl Solution {
pub fn minimum_average(mut nums: Vec<i32>) -> f64 {
nums.sort();
let n = nums.len();
let ans = (0..n / 2).map(|i| nums[i] + nums[n - i - 1]).min().unwrap();
ans as f64 / 2.0
}
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class Solution:
def minimumAverage(self, nums: List[int]) -> float:
nums.sort()
n = len(nums)
return min(nums[i] + nums[n - i - 1] for i in range(n // 2)) / 2
return min(nums[i] + nums[-i - 1] for i in range(n // 2)) / 2
```

#### Java
Expand Down Expand Up @@ -250,6 +250,19 @@ function minimumAverage(nums: number[]): number {
}
```

#### Rust

```rust
impl Solution {
pub fn minimum_average(mut nums: Vec<i32>) -> f64 {
nums.sort();
let n = nums.len();
let ans = (0..n / 2).map(|i| nums[i] + nums[n - i - 1]).min().unwrap();
ans as f64 / 2.0
}
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ class Solution:
def minimumAverage(self, nums: List[int]) -> float:
nums.sort()
n = len(nums)
return min(nums[i] + nums[n - i - 1] for i in range(n // 2)) / 2
return min(nums[i] + nums[-i - 1] for i in range(n // 2)) / 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
impl Solution {
pub fn minimum_average(mut nums: Vec<i32>) -> f64 {
nums.sort();
let n = nums.len();
let ans = (0..n / 2).map(|i| nums[i] + nums[n - i - 1]).min().unwrap();
ans as f64 / 2.0
}
}
Loading