
题目描述
给你一个长度为 n
的字符串 s
,和一个整数 k
。请你找出字符串 s
中 重复 k
次的 最长子序列 。
子序列 是由其他字符串删除某些(或不删除)字符派生而来的一个字符串。
如果 seq * k
是 s
的一个子序列,其中 seq * k
表示一个由 seq
串联 k
次构造的字符串,那么就称 seq
是字符串 s
中一个 重复 k
次 的子序列。
- 举个例子,
"bba"
是字符串 "bababcba"
中的一个重复 2
次的子序列,因为字符串 "bbabba"
是由 "bba"
串联 2
次构造的,而 "bbabba"
是字符串 "bababcba"
的一个子序列。
返回字符串 s
中 重复 k 次的最长子序列 。如果存在多个满足的子序列,则返回 字典序最大 的那个。如果不存在这样的子序列,返回一个 空 字符串。
示例 1:

输入:s = "letsleetcode", k = 2
输出:"let"
解释:存在两个最长子序列重复 2 次:let" 和 "ete" 。
"let" 是其中字典序最大的一个。
示例 2:
输入:s = "bb", k = 2
输出:"b"
解释:重复 2 次的最长子序列是 "b" 。
示例 3:
输入:s = "ab", k = 2
输出:""
解释:不存在重复 2 次的最长子序列。返回空字符串。
提示:
n == s.length
2 <= k <= 2000
2 <= n < min(2001, k * 8)
s
由小写英文字母组成
解法
方法一:BFS
我们可以先统计字符串中每个字符出现的次数,然后将出现次数大于等于 \(k\) 的字符按从小到大的顺序存入一个列表 \(\textit{cs}\) 中。接下来,我们可以使用 BFS 来枚举所有可能的子序列。
我们定义一个队列 \(\textit{q}\),初始时将空字符串放入队列中。然后,我们从队列中取出一个字符串 \(\textit{cur}\),并尝试将每个字符 \(c \in \textit{cs}\) 添加到 \(\textit{cur}\) 的末尾,形成一个新的字符串 \(\textit{nxt}\)。如果 \(\textit{nxt}\) 是一个重复 \(k\) 次的子序列,我们就将其加入到答案中,并将 \(\textit{nxt}\) 放入队列中继续处理。
我们需要一个辅助函数 \(\textit{check(t, k)}\) 来判断字符串 \(\textit{t}\) 是否是字符串 \(s\) 的一个重复 \(k\) 次的子序列。具体地,我们可以使用两个指针来遍历字符串 \(s\) 和 \(\textit{t}\),如果在遍历过程中能够找到 \(\textit{t}\) 的所有字符,并且能够重复 \(k\) 次,那么就返回 \(\textit{true}\),否则返回 \(\textit{false}\)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | class Solution:
def longestSubsequenceRepeatedK(self, s: str, k: int) -> str:
def check(t: str, k: int) -> bool:
i = 0
for c in s:
if c == t[i]:
i += 1
if i == len(t):
k -= 1
if k == 0:
return True
i = 0
return False
cnt = Counter(s)
cs = [c for c in ascii_lowercase if cnt[c] >= k]
q = deque([""])
ans = ""
while q:
cur = q.popleft()
for c in cs:
nxt = cur + c
if check(nxt, k):
ans = nxt
q.append(nxt)
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 | class Solution {
private char[] s;
public String longestSubsequenceRepeatedK(String s, int k) {
this.s = s.toCharArray();
int[] cnt = new int[26];
for (char c : this.s) {
cnt[c - 'a']++;
}
List<Character> cs = new ArrayList<>();
for (char c = 'a'; c <= 'z'; ++c) {
if (cnt[c - 'a'] >= k) {
cs.add(c);
}
}
Deque<String> q = new ArrayDeque<>();
q.offer("");
String ans = "";
while (!q.isEmpty()) {
String cur = q.poll();
for (char c : cs) {
String nxt = cur + c;
if (check(nxt, k)) {
ans = nxt;
q.offer(nxt);
}
}
}
return ans;
}
private boolean check(String t, int k) {
int i = 0;
for (char c : s) {
if (c == t.charAt(i)) {
i++;
if (i == t.length()) {
if (--k == 0) {
return true;
}
i = 0;
}
}
}
return false;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 | class Solution {
public:
string longestSubsequenceRepeatedK(string s, int k) {
auto check = [&](const string& t, int k) -> bool {
int i = 0;
for (char c : s) {
if (c == t[i]) {
i++;
if (i == t.size()) {
if (--k == 0) {
return true;
}
i = 0;
}
}
}
return false;
};
int cnt[26] = {};
for (char c : s) {
cnt[c - 'a']++;
}
vector<char> cs;
for (char c = 'a'; c <= 'z'; ++c) {
if (cnt[c - 'a'] >= k) {
cs.push_back(c);
}
}
queue<string> q;
q.push("");
string ans;
while (!q.empty()) {
string cur = q.front();
q.pop();
for (char c : cs) {
string nxt = cur + c;
if (check(nxt, k)) {
ans = nxt;
q.push(nxt);
}
}
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 | func longestSubsequenceRepeatedK(s string, k int) string {
check := func(t string, k int) bool {
i := 0
for _, c := range s {
if byte(c) == t[i] {
i++
if i == len(t) {
k--
if k == 0 {
return true
}
i = 0
}
}
}
return false
}
cnt := [26]int{}
for i := 0; i < len(s); i++ {
cnt[s[i]-'a']++
}
cs := []byte{}
for c := byte('a'); c <= 'z'; c++ {
if cnt[c-'a'] >= k {
cs = append(cs, c)
}
}
q := []string{""}
ans := ""
for len(q) > 0 {
cur := q[0]
q = q[1:]
for _, c := range cs {
nxt := cur + string(c)
if check(nxt, k) {
ans = nxt
q = append(q, nxt)
}
}
}
return ans
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 | function longestSubsequenceRepeatedK(s: string, k: number): string {
const check = (t: string, k: number): boolean => {
let i = 0;
for (const c of s) {
if (c === t[i]) {
i++;
if (i === t.length) {
k--;
if (k === 0) {
return true;
}
i = 0;
}
}
}
return false;
};
const cnt = new Array(26).fill(0);
for (const c of s) {
cnt[c.charCodeAt(0) - 97]++;
}
const cs: string[] = [];
for (let i = 0; i < 26; ++i) {
if (cnt[i] >= k) {
cs.push(String.fromCharCode(97 + i));
}
}
const q: string[] = [''];
let ans = '';
while (q.length > 0) {
const cur = q.shift()!;
for (const c of cs) {
const nxt = cur + c;
if (check(nxt, k)) {
ans = nxt;
q.push(nxt);
}
}
}
return ans;
}
|