diff --git a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README.md b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README.md index 971cc3b505454..95f4130216f1d 100644 --- a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README.md +++ b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README.md @@ -80,32 +80,250 @@ tags: -### 方法一 +### 方法一: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}$。 #### Python3 ```python - +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 ``` #### Java ```java - +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 cs = new ArrayList<>(); + for (char c = 'a'; c <= 'z'; ++c) { + if (cnt[c - 'a'] >= k) { + cs.add(c); + } + } + Deque 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; + } +} ``` #### C++ ```cpp - +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 cs; + for (char c = 'a'; c <= 'z'; ++c) { + if (cnt[c - 'a'] >= k) { + cs.push_back(c); + } + } + + queue 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; + } +}; ``` #### Go ```go +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 +} +``` +#### TypeScript + +```ts +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; +} ``` diff --git a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README_EN.md b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README_EN.md index 31b8034b543c5..7ec3670dc66c2 100644 --- a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README_EN.md +++ b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/README_EN.md @@ -76,32 +76,250 @@ tags: -### Solution 1 +### Solution 1: BFS + +We can first count the occurrences of each character in the string, and then store the characters that appear at least $k$ times in a list $\textit{cs}$ in ascending order. Next, we can use BFS to enumerate all possible subsequences. + +We define a queue $\textit{q}$, initially putting the empty string into the queue. Then, we take out a string $\textit{cur}$ from the queue and try to append each character $c \in \textit{cs}$ to the end of $\textit{cur}$ to form a new string $\textit{nxt}$. If $\textit{nxt}$ is a subsequence that can be repeated $k$ times, we add it to the answer and put $\textit{nxt}$ back into the queue for further processing. + +We need an auxiliary function $\textit{check(t, k)}$ to determine whether the string $\textit{t}$ is a repeated $k$ times subsequence of string $s$. Specifically, we can use two pointers to traverse $s$ and $\textit{t}$. If we can find all characters of $\textit{t}$ in $s$ and repeat this process $k$ times, then return $\textit{true}$; otherwise, return $\textit{false}$. #### Python3 ```python - +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 ``` #### Java ```java - +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 cs = new ArrayList<>(); + for (char c = 'a'; c <= 'z'; ++c) { + if (cnt[c - 'a'] >= k) { + cs.add(c); + } + } + Deque 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; + } +} ``` #### C++ ```cpp - +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 cs; + for (char c = 'a'; c <= 'z'; ++c) { + if (cnt[c - 'a'] >= k) { + cs.push_back(c); + } + } + + queue 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; + } +}; ``` #### Go ```go +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 +} +``` +#### TypeScript + +```ts +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; +} ``` diff --git a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.cpp b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.cpp new file mode 100644 index 0000000000000..8a7ad8569e9ca --- /dev/null +++ b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.cpp @@ -0,0 +1,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 cs; + for (char c = 'a'; c <= 'z'; ++c) { + if (cnt[c - 'a'] >= k) { + cs.push_back(c); + } + } + + queue 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; + } +}; diff --git a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.go b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.go new file mode 100644 index 0000000000000..9aebe716c2c08 --- /dev/null +++ b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.go @@ -0,0 +1,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 +} diff --git a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.java b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.java new file mode 100644 index 0000000000000..11573eda7c6ee --- /dev/null +++ b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.java @@ -0,0 +1,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 cs = new ArrayList<>(); + for (char c = 'a'; c <= 'z'; ++c) { + if (cnt[c - 'a'] >= k) { + cs.add(c); + } + } + Deque 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; + } +} \ No newline at end of file diff --git a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.py b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.py new file mode 100644 index 0000000000000..fdb26b136fcb3 --- /dev/null +++ b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.py @@ -0,0 +1,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 diff --git a/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.ts b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.ts new file mode 100644 index 0000000000000..1c93ee58da115 --- /dev/null +++ b/solution/2000-2099/2014.Longest Subsequence Repeated k Times/Solution.ts @@ -0,0 +1,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; +}