Skip to content
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

feat: add solutions to lc problem: No.1553 #2794

Merged
merged 1 commit into from
May 12, 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 @@ -69,13 +69,30 @@

### 方法一:记忆化搜索

根据题目描述,对于每个 $n$,我们可以选择三种方式之一:

1. 将 $n$ 减少 $1$;
2. 如果 $n$ 能被 $2$ 整除,将 $n$ 的值除以 $2$;
3. 如果 $n$ 能被 $3$ 整除,将 $n$ 的值除以 $3$。

因此,问题等价于求解通过上述三种方式,将 $n$ 减少到 $0$ 的最少天数。

我们设计一个函数 $dfs(n)$,表示将 $n$ 减少到 $0$ 的最少天数。函数 $dfs(n)$ 的执行过程如下:

1. 如果 $n < 2$,返回 $n$;
2. 否则,我们可以先通过 $n \bmod 2$ 次操作 $1$,将 $n$ 减少到 $2$ 的倍数,然后执行操作 $2$,将 $n$ 减少到 $n/2$;我们也可以先通过 $n \bmod 3$ 次操作 $1$,将 $n$ 减少到 $3$ 的倍数,然后执行操作 $3$,将 $n$ 减少到 $n/3$。我们选择上述两种方式中最少的一种,即 $1 + \min(n \bmod 2 + dfs(n/2), n \bmod 3 + dfs(n/3))$。

为了避免重复计算,我们使用记忆化搜索的方法,将已经计算过的 $dfs(n)$ 的值存储在哈希表中。

时间复杂度 $O(\log^2 n)$,空间复杂度 $O(\log^2 n)$。

<!-- tabs:start -->

```python
class Solution:
def minDays(self, n: int) -> int:
@cache
def dfs(n):
def dfs(n: int) -> int:
if n < 2:
return n
return 1 + min(n % 2 + dfs(n // 2), n % 3 + dfs(n // 3))
Expand Down Expand Up @@ -115,8 +132,12 @@ public:
}

int dfs(int n) {
if (n < 2) return n;
if (f.count(n)) return f[n];
if (n < 2) {
return n;
}
if (f.count(n)) {
return f[n];
}
int res = 1 + min(n % 2 + dfs(n / 2), n % 3 + dfs(n / 3));
f[n] = res;
return res;
Expand All @@ -140,6 +161,23 @@ func minDays(n int) int {
}
```

```ts
function minDays(n: number): number {
const f: Record<number, number> = {};
const dfs = (n: number): number => {
if (n < 2) {
return n;
}
if (f[n] !== undefined) {
return f[n];
}
f[n] = 1 + Math.min((n % 2) + dfs((n / 2) | 0), (n % 3) + dfs((n / 3) | 0));
return f[n];
};
return dfs(n);
}
```

<!-- tabs:end -->

<!-- end -->
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,32 @@ You need at least 3 days to eat the 6 oranges.

## Solutions

### Solution 1
### Solution 1: Memoization Search

According to the problem description, for each $n$, we can choose one of three ways:

1. Decrease $n$ by $1$;
2. If $n$ can be divided by $2$, divide the value of $n$ by $2$;
3. If $n$ can be divided by $3$, divide the value of $n$ by $3$.

Therefore, the problem is equivalent to finding the minimum number of days to reduce $n$ to $0$ through the above three ways.

We design a function $dfs(n)$, which represents the minimum number of days to reduce $n$ to $0$. The execution process of the function $dfs(n)$ is as follows:

1. If $n < 2$, return $n$;
2. Otherwise, we can first reduce $n$ to a multiple of $2$ by $n \bmod 2$ operations of $1$, and then perform operation $2$ to reduce $n$ to $n/2$; we can also first reduce $n$ to a multiple of $3$ by $n \bmod 3$ operations of $1$, and then perform operation $3$ to reduce $n$ to $n/3$. We choose the minimum of the above two ways, that is, $1 + \min(n \bmod 2 + dfs(n/2), n \bmod 3 + dfs(n/3))$.

To avoid repeated calculations, we use the method of memoization search and store the calculated values of $dfs(n)$ in a hash table.

The time complexity is $O(\log^2 n)$, and the space complexity is $O(\log^2 n)$.

<!-- tabs:start -->

```python
class Solution:
def minDays(self, n: int) -> int:
@cache
def dfs(n):
def dfs(n: int) -> int:
if n < 2:
return n
return 1 + min(n % 2 + dfs(n // 2), n % 3 + dfs(n // 3))
Expand Down Expand Up @@ -101,8 +118,12 @@ public:
}

int dfs(int n) {
if (n < 2) return n;
if (f.count(n)) return f[n];
if (n < 2) {
return n;
}
if (f.count(n)) {
return f[n];
}
int res = 1 + min(n % 2 + dfs(n / 2), n % 3 + dfs(n / 3));
f[n] = res;
return res;
Expand All @@ -126,6 +147,23 @@ func minDays(n int) int {
}
```

```ts
function minDays(n: number): number {
const f: Record<number, number> = {};
const dfs = (n: number): number => {
if (n < 2) {
return n;
}
if (f[n] !== undefined) {
return f[n];
}
f[n] = 1 + Math.min((n % 2) + dfs((n / 2) | 0), (n % 3) + dfs((n / 3) | 0));
return f[n];
};
return dfs(n);
}
```

<!-- tabs:end -->

<!-- end -->
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ class Solution {
}

int dfs(int n) {
if (n < 2) return n;
if (f.count(n)) return f[n];
if (n < 2) {
return n;
}
if (f.count(n)) {
return f[n];
}
int res = 1 + min(n % 2 + dfs(n / 2), n % 3 + dfs(n / 3));
f[n] = res;
return res;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Solution:
def minDays(self, n: int) -> int:
@cache
def dfs(n):
def dfs(n: int) -> int:
if n < 2:
return n
return 1 + min(n % 2 + dfs(n // 2), n % 3 + dfs(n // 3))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function minDays(n: number): number {
const f: Record<number, number> = {};
const dfs = (n: number): number => {
if (n < 2) {
return n;
}
if (f[n] !== undefined) {
return f[n];
}
f[n] = 1 + Math.min((n % 2) + dfs((n / 2) | 0), (n % 3) + dfs((n / 3) | 0));
return f[n];
};
return dfs(n);
}
Loading