Skip to content

feat: update solutions to lc problems: No.2900,2901 #4408

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 2 commits into from
May 14, 2025
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 @@ -87,17 +87,16 @@ tags:

```python
class Solution:
def getWordsInLongestSubsequence(
self, n: int, words: List[str], groups: List[int]
) -> List[str]:
def getLongestSubsequence(self, words: List[str], groups: List[int]) -> List[str]:
return [words[i] for i, x in enumerate(groups) if i == 0 or x != groups[i - 1]]
```

#### Java

```java
class Solution {
public List<String> getWordsInLongestSubsequence(int n, String[] words, int[] groups) {
public List<String> getLongestSubsequence(String[] words, int[] groups) {
int n = groups.length;
List<String> ans = new ArrayList<>();
for (int i = 0; i < n; ++i) {
if (i == 0 || groups[i] != groups[i - 1]) {
Expand All @@ -114,7 +113,8 @@ class Solution {
```cpp
class Solution {
public:
vector<string> getWordsInLongestSubsequence(int n, vector<string>& words, vector<int>& groups) {
vector<string> getLongestSubsequence(vector<string>& words, vector<int>& groups) {
int n = groups.size();
vector<string> ans;
for (int i = 0; i < n; ++i) {
if (i == 0 || groups[i] != groups[i - 1]) {
Expand All @@ -129,7 +129,7 @@ public:
#### Go

```go
func getWordsInLongestSubsequence(n int, words []string, groups []int) (ans []string) {
func getLongestSubsequence(words []string, groups []int) (ans []string) {
for i, x := range groups {
if i == 0 || x != groups[i-1] {
ans = append(ans, words[i])
Expand All @@ -142,9 +142,9 @@ func getWordsInLongestSubsequence(n int, words []string, groups []int) (ans []st
#### TypeScript

```ts
function getWordsInLongestSubsequence(n: number, words: string[], groups: number[]): string[] {
function getLongestSubsequence(words: string[], groups: number[]): string[] {
const ans: string[] = [];
for (let i = 0; i < n; ++i) {
for (let i = 0; i < groups.length; ++i) {
if (i === 0 || groups[i] !== groups[i - 1]) {
ans.push(words[i]);
}
Expand All @@ -157,19 +157,13 @@ function getWordsInLongestSubsequence(n: number, words: string[], groups: number

```rust
impl Solution {
pub fn get_words_in_longest_subsequence(
n: i32,
words: Vec<String>,
groups: Vec<i32>,
) -> Vec<String> {
let mut ans = vec![];

for i in 0..n {
if i == 0 || groups[i as usize] != groups[(i - 1) as usize] {
ans.push(words[i as usize].clone());
pub fn get_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
let mut ans = Vec::new();
for (i, &g) in groups.iter().enumerate() {
if i == 0 || g != groups[i - 1] {
ans.push(words[i].clone());
}
}

ans
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,16 @@ The time complexity is $O(n)$, where $n$ is the length of the array $groups$. Th

```python
class Solution:
def getWordsInLongestSubsequence(
self, n: int, words: List[str], groups: List[int]
) -> List[str]:
def getLongestSubsequence(self, words: List[str], groups: List[int]) -> List[str]:
return [words[i] for i, x in enumerate(groups) if i == 0 or x != groups[i - 1]]
```

#### Java

```java
class Solution {
public List<String> getWordsInLongestSubsequence(int n, String[] words, int[] groups) {
public List<String> getLongestSubsequence(String[] words, int[] groups) {
int n = groups.length;
List<String> ans = new ArrayList<>();
for (int i = 0; i < n; ++i) {
if (i == 0 || groups[i] != groups[i - 1]) {
Expand All @@ -138,7 +137,8 @@ class Solution {
```cpp
class Solution {
public:
vector<string> getWordsInLongestSubsequence(int n, vector<string>& words, vector<int>& groups) {
vector<string> getLongestSubsequence(vector<string>& words, vector<int>& groups) {
int n = groups.size();
vector<string> ans;
for (int i = 0; i < n; ++i) {
if (i == 0 || groups[i] != groups[i - 1]) {
Expand All @@ -153,7 +153,7 @@ public:
#### Go

```go
func getWordsInLongestSubsequence(n int, words []string, groups []int) (ans []string) {
func getLongestSubsequence(words []string, groups []int) (ans []string) {
for i, x := range groups {
if i == 0 || x != groups[i-1] {
ans = append(ans, words[i])
Expand All @@ -166,9 +166,9 @@ func getWordsInLongestSubsequence(n int, words []string, groups []int) (ans []st
#### TypeScript

```ts
function getWordsInLongestSubsequence(n: number, words: string[], groups: number[]): string[] {
function getLongestSubsequence(words: string[], groups: number[]): string[] {
const ans: string[] = [];
for (let i = 0; i < n; ++i) {
for (let i = 0; i < groups.length; ++i) {
if (i === 0 || groups[i] !== groups[i - 1]) {
ans.push(words[i]);
}
Expand All @@ -181,19 +181,13 @@ function getWordsInLongestSubsequence(n: number, words: string[], groups: number

```rust
impl Solution {
pub fn get_words_in_longest_subsequence(
n: i32,
words: Vec<String>,
groups: Vec<i32>,
) -> Vec<String> {
let mut ans = vec![];

for i in 0..n {
if i == 0 || groups[i as usize] != groups[(i - 1) as usize] {
ans.push(words[i as usize].clone());
pub fn get_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
let mut ans = Vec::new();
for (i, &g) in groups.iter().enumerate() {
if i == 0 || g != groups[i - 1] {
ans.push(words[i].clone());
}
}

ans
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Solution {
public:
vector<string> getWordsInLongestSubsequence(int n, vector<string>& words, vector<int>& groups) {
vector<string> getLongestSubsequence(vector<string>& words, vector<int>& groups) {
int n = groups.size();
vector<string> ans;
for (int i = 0; i < n; ++i) {
if (i == 0 || groups[i] != groups[i - 1]) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
func getWordsInLongestSubsequence(n int, words []string, groups []int) (ans []string) {
func getLongestSubsequence(words []string, groups []int) (ans []string) {
for i, x := range groups {
if i == 0 || x != groups[i-1] {
ans = append(ans, words[i])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Solution {
public List<String> getWordsInLongestSubsequence(int n, String[] words, int[] groups) {
public List<String> getLongestSubsequence(String[] words, int[] groups) {
int n = groups.length;
List<String> ans = new ArrayList<>();
for (int i = 0; i < n; ++i) {
if (i == 0 || groups[i] != groups[i - 1]) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
class Solution:
def getWordsInLongestSubsequence(
self, n: int, words: List[str], groups: List[int]
) -> List[str]:
def getLongestSubsequence(self, words: List[str], groups: List[int]) -> List[str]:
return [words[i] for i, x in enumerate(groups) if i == 0 or x != groups[i - 1]]
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
impl Solution {
pub fn get_words_in_longest_subsequence(
n: i32,
words: Vec<String>,
groups: Vec<i32>,
) -> Vec<String> {
let mut ans = vec![];

for i in 0..n {
if i == 0 || groups[i as usize] != groups[(i - 1) as usize] {
ans.push(words[i as usize].clone());
pub fn get_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
let mut ans = Vec::new();
for (i, &g) in groups.iter().enumerate() {
if i == 0 || g != groups[i - 1] {
ans.push(words[i].clone());
}
}

ans
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function getWordsInLongestSubsequence(n: number, words: string[], groups: number[]): string[] {
function getLongestSubsequence(words: string[], groups: number[]): string[] {
const ans: string[] = [];
for (let i = 0; i < n; ++i) {
for (let i = 0; i < groups.length; ++i) {
if (i === 0 || groups[i] !== groups[i - 1]) {
ans.push(words[i]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,12 @@ tags:
```python
class Solution:
def getWordsInLongestSubsequence(
self, n: int, words: List[str], groups: List[int]
self, words: List[str], groups: List[int]
) -> List[str]:
def check(s: str, t: str) -> bool:
return len(s) == len(t) and sum(a != b for a, b in zip(s, t)) == 1

n = len(groups)
f = [1] * n
g = [-1] * n
mx = 1
Expand All @@ -132,7 +133,8 @@ class Solution:

```java
class Solution {
public List<String> getWordsInLongestSubsequence(int n, String[] words, int[] groups) {
public List<String> getWordsInLongestSubsequence(String[] words, int[] groups) {
int n = groups.length;
int[] f = new int[n];
int[] g = new int[n];
Arrays.fill(f, 1);
Expand Down Expand Up @@ -180,7 +182,7 @@ class Solution {
```cpp
class Solution {
public:
vector<string> getWordsInLongestSubsequence(int n, vector<string>& words, vector<int>& groups) {
vector<string> getWordsInLongestSubsequence(vector<string>& words, vector<int>& groups) {
auto check = [](string& s, string& t) {
if (s.size() != t.size()) {
return false;
Expand All @@ -191,6 +193,7 @@ public:
}
return cnt == 1;
};
int n = groups.size();
vector<int> f(n, 1);
vector<int> g(n, -1);
int mx = 1;
Expand Down Expand Up @@ -221,7 +224,7 @@ public:
#### Go

```go
func getWordsInLongestSubsequence(n int, words []string, groups []int) []string {
func getWordsInLongestSubsequence(words []string, groups []int) []string {
check := func(s, t string) bool {
if len(s) != len(t) {
return false
Expand All @@ -234,6 +237,7 @@ func getWordsInLongestSubsequence(n int, words []string, groups []int) []string
}
return cnt == 1
}
n := len(groups)
f := make([]int, n)
g := make([]int, n)
for i := range f {
Expand Down Expand Up @@ -261,17 +265,16 @@ func getWordsInLongestSubsequence(n int, words []string, groups []int) []string
break
}
}
for i, j := 0, len(ans)-1; i < j; i, j = i+1, j-1 {
ans[i], ans[j] = ans[j], ans[i]
}
slices.Reverse(ans)
return ans
}
```

#### TypeScript

```ts
function getWordsInLongestSubsequence(n: number, words: string[], groups: number[]): string[] {
function getWordsInLongestSubsequence(words: string[], groups: number[]): string[] {
const n = groups.length;
const f: number[] = Array(n).fill(1);
const g: number[] = Array(n).fill(-1);
let mx = 1;
Expand Down Expand Up @@ -313,16 +316,12 @@ function getWordsInLongestSubsequence(n: number, words: string[], groups: number

```rust
impl Solution {
pub fn get_words_in_longest_subsequence(
n: i32,
words: Vec<String>,
groups: Vec<i32>,
) -> Vec<String> {
pub fn get_words_in_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
fn check(s: &str, t: &str) -> bool {
s.len() == t.len() && s.chars().zip(t.chars()).filter(|(a, b)| a != b).count() == 1
}

let n = n as usize;
let n = groups.len();

let mut f = vec![1; n];
let mut g = vec![-1; n];
Expand Down Expand Up @@ -364,66 +363,4 @@ impl Solution {

<!-- solution:end -->

<!-- solution:start -->

### 方法二:动态规划 + 通配符哈希表

在方法一中,我们需要枚举所有的 $i$ 和 $j$ 组合, 这一步可以通过维护一个通配符哈希表来优化. 对于每个字符串 $word[i]$, 我们枚举它的每个字符, 将其替换为通配符, 然后将替换后的字符串作为键, 将其下标作为值存入哈希表中. 这样我们可以在 $O(L)$ 时间内找到所有距离 $word[i]$ 汉明距离为 1 的 $word[j]$. 尽管时间复杂度仍然是 $O(n^2 \times L)$, 但平均复杂度会有所降低.

<!-- tabs:start -->

#### Java

```java
class Solution {
public List<String> getWordsInLongestSubsequence(int n, String[] words, int[] groups) {
int[] dp = new int[n];
int[] next = new int[n];
Map<String, List<Integer>> strToIdxMap = new HashMap<>();
int maxIdx = n;
for (int i = n - 1; i >= 0; i--) {
int prevIdx = n;
char[] word = words[i].toCharArray();
for (int j = 0; j < word.length; j++) {
// convert word to pattern with '*'.
char temp = word[j];
word[j] = '*';
String curr = new String(word);

// search matches and update dp.
List<Integer> prevList = strToIdxMap.getOrDefault(curr, List.of());
for (int prev : prevList) {
if (groups[prev] == groups[i] || dp[prev] < dp[i]) {
continue;
}
dp[i] = dp[prev] + 1;
prevIdx = prev;
}

// append current pattern to dictionary.
strToIdxMap.computeIfAbsent(curr, k -> new ArrayList<>()).add(i);

// restore pattern to orignal word.
word[j] = temp;
}
if (maxIdx >= n || dp[i] > dp[maxIdx]) {
maxIdx = i;
}
next[i] = prevIdx;
}
int curr = maxIdx;
List<String> ans = new ArrayList<>();
while (curr < n) {
ans.add(words[curr]);
curr = next[curr];
}
return ans;
}
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
Loading