Skip to content

feat: add solutions to lc problems: No.2135~2137 #3157

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 1 commit into from
Jun 24, 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 @@ -88,7 +88,13 @@ tags:

<!-- solution:start -->

### 方法一
### 方法一:哈希表 + 位运算

我们注意到,题目中给定的字符串只包含小写字母,并且每个字符串的字母至多出现一次。因此,我们可以用一个长度为 $26$ 的二进制数表示一个字符串,其中第 $i$ 位为 $1$ 表示字符串中包含第 $i$ 个小写字母,为 $0$ 表示字符串中不包含第 $i$ 个小写字母。

我们可以将字符串数组 $\text{startWords}$ 中的每个字符串转换为一个二进制数,并将这些二进制数存储到一个集合 $\text{s}$ 中。对于字符串数组 $\text{targetWords}$ 中的每个字符串,我们首先将其转换为一个二进制数,然后枚举这个字符串中的每个字母,将这个字母从二进制数中去掉,再检查是否存在一个二进制数在集合 $\text{s}$ 中,使得这个二进制数与去掉的字母的二进制数的异或结果在集合 $\text{s}$ 中,如果存在,那么这个字符串可以由 $\text{startWords}$ 中的某个字符串执行转换操作获得,答案加一。然后我们跳过这个字符串,继续处理下一个字符串。

时间复杂度 $O(n \times |\Sigma|)$,空间复杂度 $O(n)$。其中 $n$ 为字符串数组 $\text{targetWords}$ 的长度,而 $|\Sigma|$ 为字符串中的字符集大小,本题中 $|\Sigma| = 26$。

<!-- tabs:start -->

Expand All @@ -97,21 +103,12 @@ tags:
```python
class Solution:
def wordCount(self, startWords: List[str], targetWords: List[str]) -> int:
s = set()
for word in startWords:
mask = 0
for c in word:
mask |= 1 << (ord(c) - ord('a'))
s.add(mask)

s = {sum(1 << (ord(c) - 97) for c in w) for w in startWords}
ans = 0
for word in targetWords:
mask = 0
for c in word:
mask |= 1 << (ord(c) - ord('a'))
for c in word:
t = mask ^ (1 << (ord(c) - ord('a')))
if t in s:
for w in targetWords:
x = sum(1 << (ord(c) - 97) for c in w)
for c in w:
if x ^ (1 << (ord(c) - 97)) in s:
ans += 1
break
return ans
Expand All @@ -121,25 +118,23 @@ class Solution:

```java
class Solution {

public int wordCount(String[] startWords, String[] targetWords) {
Set<Integer> s = new HashSet<>();
for (String word : startWords) {
int mask = 0;
for (char c : word.toCharArray()) {
mask |= (1 << (c - 'a'));
for (var w : startWords) {
int x = 0;
for (var c : w.toCharArray()) {
x |= 1 << (c - 'a');
}
s.add(mask);
s.add(x);
}
int ans = 0;
for (String word : targetWords) {
int mask = 0;
for (char c : word.toCharArray()) {
mask |= (1 << (c - 'a'));
for (var w : targetWords) {
int x = 0;
for (var c : w.toCharArray()) {
x |= 1 << (c - 'a');
}
for (char c : word.toCharArray()) {
int t = mask ^ (1 << (c - 'a'));
if (s.contains(t)) {
for (var c : w.toCharArray()) {
if (s.contains(x ^ (1 << (c - 'a')))) {
++ans;
break;
}
Expand All @@ -157,20 +152,21 @@ class Solution {
public:
int wordCount(vector<string>& startWords, vector<string>& targetWords) {
unordered_set<int> s;
for (auto& word : startWords) {
int mask = 0;
for (char c : word)
mask |= (1 << (c - 'a'));
s.insert(mask);
for (auto& w : startWords) {
int x = 0;
for (char c : w) {
x |= 1 << (c - 'a');
}
s.insert(x);
}
int ans = 0;
for (auto& word : targetWords) {
int mask = 0;
for (char c : word)
mask |= (1 << (c - 'a'));
for (char c : word) {
int t = mask ^ (1 << (c - 'a'));
if (s.count(t)) {
for (auto& w : targetWords) {
int x = 0;
for (char c : w) {
x |= 1 << (c - 'a');
}
for (char c : w) {
if (s.contains(x ^ (1 << (c - 'a')))) {
++ans;
break;
}
Expand All @@ -184,30 +180,57 @@ public:
#### Go

```go
func wordCount(startWords []string, targetWords []string) int {
s := make(map[int]bool)
for _, word := range startWords {
mask := 0
for _, c := range word {
mask |= (1 << (c - 'a'))
func wordCount(startWords []string, targetWords []string) (ans int) {
s := map[int]bool{}
for _, w := range startWords {
x := 0
for _, c := range w {
x |= 1 << (c - 'a')
}
s[mask] = true
s[x] = true
}
ans := 0
for _, word := range targetWords {
mask := 0
for _, c := range word {
mask |= (1 << (c - 'a'))
for _, w := range targetWords {
x := 0
for _, c := range w {
x |= 1 << (c - 'a')
}
for _, c := range word {
t := mask ^ (1 << (c - 'a'))
if s[t] {
for _, c := range w {
if s[x^(1<<(c-'a'))] {
ans++
break
}
}
}
return ans
return
}
```

#### TypeScript

```ts
function wordCount(startWords: string[], targetWords: string[]): number {
const s = new Set<number>();
for (const w of startWords) {
let x = 0;
for (const c of w) {
x ^= 1 << (c.charCodeAt(0) - 97);
}
s.add(x);
}
let ans = 0;
for (const w of targetWords) {
let x = 0;
for (const c of w) {
x ^= 1 << (c.charCodeAt(0) - 97);
}
for (const c of w) {
if (s.has(x ^ (1 << (c.charCodeAt(0) - 97)))) {
++ans;
break;
}
}
}
return ans;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ tags:

<!-- solution:start -->

### Solution 1
### Solution 1: Hash Table + Bit Manipulation

We notice that the given strings only contain lowercase letters, and each letter in a string appears at most once. Therefore, we can represent a string with a binary number of length $26$, where the $i$-th bit being $1$ indicates that the string contains the $i$-th lowercase letter, and $0$ indicates the absence of the $i$-th lowercase letter.

We can convert each string in the array $\text{startWords}$ into a binary number and store these binary numbers in a set $\text{s}$. For each string in the array $\text{targetWords}$, we first convert it into a binary number, then enumerate each letter in this string, remove this letter from the binary number, and check if there exists a binary number in the set $\text{s}$ such that the XOR result of this binary number with the removed letter's binary number is in the set $\text{s}$. If such a binary number exists, then this string can be obtained by performing a transformation operation on some string in $\text{startWords}$, and we increment the answer by one. Then, we skip this string and continue processing the next string.

The time complexity is $O(n \times |\Sigma|)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string array $\text{targetWords}$, and $|\Sigma|$ is the size of the character set in the string, which is $26$ in this problem.

<!-- tabs:start -->

Expand All @@ -95,21 +101,12 @@ tags:
```python
class Solution:
def wordCount(self, startWords: List[str], targetWords: List[str]) -> int:
s = set()
for word in startWords:
mask = 0
for c in word:
mask |= 1 << (ord(c) - ord('a'))
s.add(mask)

s = {sum(1 << (ord(c) - 97) for c in w) for w in startWords}
ans = 0
for word in targetWords:
mask = 0
for c in word:
mask |= 1 << (ord(c) - ord('a'))
for c in word:
t = mask ^ (1 << (ord(c) - ord('a')))
if t in s:
for w in targetWords:
x = sum(1 << (ord(c) - 97) for c in w)
for c in w:
if x ^ (1 << (ord(c) - 97)) in s:
ans += 1
break
return ans
Expand All @@ -119,25 +116,23 @@ class Solution:

```java
class Solution {

public int wordCount(String[] startWords, String[] targetWords) {
Set<Integer> s = new HashSet<>();
for (String word : startWords) {
int mask = 0;
for (char c : word.toCharArray()) {
mask |= (1 << (c - 'a'));
for (var w : startWords) {
int x = 0;
for (var c : w.toCharArray()) {
x |= 1 << (c - 'a');
}
s.add(mask);
s.add(x);
}
int ans = 0;
for (String word : targetWords) {
int mask = 0;
for (char c : word.toCharArray()) {
mask |= (1 << (c - 'a'));
for (var w : targetWords) {
int x = 0;
for (var c : w.toCharArray()) {
x |= 1 << (c - 'a');
}
for (char c : word.toCharArray()) {
int t = mask ^ (1 << (c - 'a'));
if (s.contains(t)) {
for (var c : w.toCharArray()) {
if (s.contains(x ^ (1 << (c - 'a')))) {
++ans;
break;
}
Expand All @@ -155,20 +150,21 @@ class Solution {
public:
int wordCount(vector<string>& startWords, vector<string>& targetWords) {
unordered_set<int> s;
for (auto& word : startWords) {
int mask = 0;
for (char c : word)
mask |= (1 << (c - 'a'));
s.insert(mask);
for (auto& w : startWords) {
int x = 0;
for (char c : w) {
x |= 1 << (c - 'a');
}
s.insert(x);
}
int ans = 0;
for (auto& word : targetWords) {
int mask = 0;
for (char c : word)
mask |= (1 << (c - 'a'));
for (char c : word) {
int t = mask ^ (1 << (c - 'a'));
if (s.count(t)) {
for (auto& w : targetWords) {
int x = 0;
for (char c : w) {
x |= 1 << (c - 'a');
}
for (char c : w) {
if (s.contains(x ^ (1 << (c - 'a')))) {
++ans;
break;
}
Expand All @@ -182,30 +178,57 @@ public:
#### Go

```go
func wordCount(startWords []string, targetWords []string) int {
s := make(map[int]bool)
for _, word := range startWords {
mask := 0
for _, c := range word {
mask |= (1 << (c - 'a'))
func wordCount(startWords []string, targetWords []string) (ans int) {
s := map[int]bool{}
for _, w := range startWords {
x := 0
for _, c := range w {
x |= 1 << (c - 'a')
}
s[mask] = true
s[x] = true
}
ans := 0
for _, word := range targetWords {
mask := 0
for _, c := range word {
mask |= (1 << (c - 'a'))
for _, w := range targetWords {
x := 0
for _, c := range w {
x |= 1 << (c - 'a')
}
for _, c := range word {
t := mask ^ (1 << (c - 'a'))
if s[t] {
for _, c := range w {
if s[x^(1<<(c-'a'))] {
ans++
break
}
}
}
return ans
return
}
```

#### TypeScript

```ts
function wordCount(startWords: string[], targetWords: string[]): number {
const s = new Set<number>();
for (const w of startWords) {
let x = 0;
for (const c of w) {
x ^= 1 << (c.charCodeAt(0) - 97);
}
s.add(x);
}
let ans = 0;
for (const w of targetWords) {
let x = 0;
for (const c of w) {
x ^= 1 << (c.charCodeAt(0) - 97);
}
for (const c of w) {
if (s.has(x ^ (1 << (c.charCodeAt(0) - 97)))) {
++ans;
break;
}
}
}
return ans;
}
```

Expand Down
Loading