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.3144 #2810

Merged
merged 2 commits into from
May 13, 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 @@ -51,24 +51,198 @@

## 解法

### 方法一
### 方法一:记忆化搜索 + 哈希表

我们设计一个函数 $\text{dfs}(i)$,表示从字符串 $s[i]$ 开始分割的最少子字符串数量。那么答案就是 $\text{dfs}(0)$。

函数 $\text{dfs}(i)$ 的计算过程如下:

如果 $i \geq n$,表示已经处理完了所有字符,返回 $0$。

否则,我们维护一个哈希表 $\text{cnt}$,表示当前子字符串中每个字符出现的次数。另外,我们还维护一个哈希表 $\text{freq}$,表示每个字符出现的次数的频率。

然后我们枚举 $j$ 从 $i$ 到 $n-1$,表示当前子字符串的结束位置。对于每个 $j$,我们更新 $\text{cnt}$ 和 $\text{freq}$,然后判断 $\text{freq}$ 的大小是否为 $1$,如果是的话,我们可以从 $j+1$ 开始分割,此时答案为 $1 + \text{dfs}(j+1)$,我们取所有 $j$ 中答案的最小值作为函数的返回值。

为了避免重复计算,我们使用记忆化搜索。

时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。

<!-- tabs:start -->

```python

class Solution:
def minimumSubstringsInPartition(self, s: str) -> int:
@cache
def dfs(i: int) -> int:
if i >= n:
return 0
cnt = defaultdict(int)
freq = defaultdict(int)
ans = n - i
for j in range(i, n):
if cnt[s[j]]:
freq[cnt[s[j]]] -= 1
if not freq[cnt[s[j]]]:
freq.pop(cnt[s[j]])
cnt[s[j]] += 1
freq[cnt[s[j]]] += 1
if len(freq) == 1 and (t := 1 + dfs(j + 1)) < ans:
ans = t
return ans

n = len(s)
return dfs(0)
```

```java

class Solution {
private int n;
private char[] s;
private Integer[] f;

public int minimumSubstringsInPartition(String s) {
n = s.length();
f = new Integer[n];
this.s = s.toCharArray();
return dfs(0);
}

private int dfs(int i) {
if (i >= n) {
return 0;
}
if (f[i] != null) {
return f[i];
}
int[] cnt = new int[26];
Map<Integer, Integer> freq = new HashMap<>(26);
int ans = n - i;
for (int j = i; j < n; ++j) {
int k = s[j] - 'a';
if (cnt[k] > 0) {
if (freq.merge(cnt[k], -1, Integer::sum) == 0) {
freq.remove(cnt[k]);
}
}
++cnt[k];
freq.merge(cnt[k], 1, Integer::sum);
if (freq.size() == 1) {
ans = Math.min(ans, 1 + dfs(j + 1));
}
}
return f[i] = ans;
}
}
```

```cpp

class Solution {
public:
int minimumSubstringsInPartition(string s) {
int n = s.size();
int f[n];
memset(f, -1, sizeof(f));
function<int(int)> dfs = [&](int i) {
if (i >= n) {
return 0;
}
if (f[i] != -1) {
return f[i];
}
f[i] = n - i;
int cnt[26]{};
unordered_map<int, int> freq;
for (int j = i; j < n; ++j) {
int k = s[j] - 'a';
if (cnt[k]) {
freq[cnt[k]]--;
if (freq[cnt[k]] == 0) {
freq.erase(cnt[k]);
}
}
++cnt[k];
++freq[cnt[k]];
if (freq.size() == 1) {
f[i] = min(f[i], 1 + dfs(j + 1));
}
}
return f[i];
};
return dfs(0);
}
};
```

```go
func minimumSubstringsInPartition(s string) int {
n := len(s)
f := make([]int, n)
for i := range f {
f[i] = -1
}
var dfs func(int) int
dfs = func(i int) int {
if i >= n {
return 0
}
if f[i] != -1 {
return f[i]
}
cnt := [26]int{}
freq := map[int]int{}
f[i] = n - i
for j := i; j < n; j++ {
k := int(s[j] - 'a')
if cnt[k] > 0 {
freq[cnt[k]]--
if freq[cnt[k]] == 0 {
delete(freq, cnt[k])
}
}
cnt[k]++
freq[cnt[k]]++
if len(freq) == 1 {
f[i] = min(f[i], 1+dfs(j+1))
}
}
return f[i]
}
return dfs(0)
}
```

```ts
function minimumSubstringsInPartition(s: string): number {
const n = s.length;
const f: number[] = Array(n).fill(-1);
const dfs = (i: number): number => {
if (i >= n) {
return 0;
}
if (f[i] !== -1) {
return f[i];
}
const cnt: Map<number, number> = new Map();
const freq: Map<number, number> = new Map();
f[i] = n - i;
for (let j = i; j < n; ++j) {
const k = s.charCodeAt(j) - 97;
if (freq.has(cnt.get(k)!)) {
freq.set(cnt.get(k)!, freq.get(cnt.get(k)!)! - 1);
if (freq.get(cnt.get(k)!) === 0) {
freq.delete(cnt.get(k)!);
}
}
cnt.set(k, (cnt.get(k) || 0) + 1);
freq.set(cnt.get(k)!, (freq.get(cnt.get(k)!) || 0) + 1);
if (freq.size === 1) {
f[i] = Math.min(f[i], 1 + dfs(j + 1));
}
}
return f[i];
};
return dfs(0);
}
```

<!-- tabs:end -->
Expand Down
Loading
Loading