Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.1930 (#4033)
Browse files Browse the repository at this point in the history
No.1930.Unique Length-3 Palindromic Subsequences
  • Loading branch information
yanglbme authored Feb 6, 2025
1 parent 4b836c8 commit c6fa041
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ tags:

枚举结束后,即可得到答案。

时间复杂度 $O(n \times C)$,空间复杂度 $O(C)$,其中 $n$ 为字符串长度,而 $C$ 为字符集大小本题中 $C = 26$。
时间复杂度 $O(n \times |\Sigma|)$,其中 $n$ 为字符串长度,而 $\Sigma$ 为字符集大小本题中 $|\Sigma| = 26$。空间复杂度 $O(|\Sigma|)$ 或 $O(1)$。

<!-- tabs:start -->

Expand All @@ -112,11 +112,14 @@ class Solution {
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.indexOf(c), r = s.lastIndexOf(c);
Set<Character> cs = new HashSet<>();
int mask = 0;
for (int i = l + 1; i < r; ++i) {
cs.add(s.charAt(i));
int j = s.charAt(i) - 'a';
if ((mask >> j & 1) == 0) {
mask |= 1 << j;
++ans;
}
}
ans += cs.size();
}
return ans;
}
Expand All @@ -132,9 +135,14 @@ public:
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.find_first_of(c), r = s.find_last_of(c);
unordered_set<char> cs;
for (int i = l + 1; i < r; ++i) cs.insert(s[i]);
ans += cs.size();
int mask = 0;
for (int i = l + 1; i < r; ++i) {
int j = s[i] - 'a';
if (mask >> j & 1 ^ 1) {
mask |= 1 << j;
++ans;
}
}
}
return ans;
}
Expand All @@ -147,80 +155,88 @@ public:
func countPalindromicSubsequence(s string) (ans int) {
for c := 'a'; c <= 'z'; c++ {
l, r := strings.Index(s, string(c)), strings.LastIndex(s, string(c))
cs := map[byte]struct{}{}
mask := 0
for i := l + 1; i < r; i++ {
cs[s[i]] = struct{}{}
j := int(s[i] - 'a')
if mask>>j&1 == 0 {
mask |= 1 << j
ans++
}
}
ans += len(cs)
}
return
}
```

#### C#

```cs
public class Solution {
public int CountPalindromicSubsequence(string s) {
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.IndexOf(c), r = s.LastIndexOf(c);
HashSet<char> cs = new HashSet<char>();
for (int i = l + 1; i < r; ++i) {
cs.Add(s[i]);
}
ans += cs.Count;
}
return ans;
}
}
```

#### TypeScript

```ts
export function countPalindromicSubsequence(s: string): number {
const cnt = new Map<string, [number, number]>();
const n = s.length;
function countPalindromicSubsequence(s: string): number {
let ans = 0;

for (let i = 0; i < n; i++) {
const ch = s[i];
if (cnt.has(ch)) cnt.get(ch)![1] = i;
else cnt.set(ch, [i, i]);
}

for (const [_, [i, j]] of cnt) {
if (i !== j) {
ans += new Set(s.slice(i + 1, j)).size;
const a = 'a'.charCodeAt(0);
for (let ch = 0; ch < 26; ++ch) {
const c = String.fromCharCode(ch + a);
const l = s.indexOf(c);
const r = s.lastIndexOf(c);
let mask = 0;
for (let i = l + 1; i < r; ++i) {
const j = s.charCodeAt(i) - a;
if (((mask >> j) & 1) ^ 1) {
mask |= 1 << j;
++ans;
}
}
}

return ans;
}
```

#### JavaScript

```js
export function countPalindromicSubsequence(s) {
const cnt = new Map();
const n = s.length;
/**
* @param {string} s
* @return {number}
*/
var countPalindromicSubsequence = function (s) {
let ans = 0;

for (let i = 0; i < n; i++) {
const ch = s[i];
if (cnt.has(ch)) cnt.get(ch)[1] = i;
else cnt.set(ch, [i, i]);
const a = 'a'.charCodeAt(0);
for (let ch = 0; ch < 26; ++ch) {
const c = String.fromCharCode(ch + a);
const l = s.indexOf(c);
const r = s.lastIndexOf(c);
let mask = 0;
for (let i = l + 1; i < r; ++i) {
const j = s.charCodeAt(i) - a;
if (((mask >> j) & 1) ^ 1) {
mask |= 1 << j;
++ans;
}
}
}
return ans;
};
```

for (const [_, [i, j]] of cnt) {
if (i !== j) {
ans += new Set(s.slice(i + 1, j)).size;
#### C#

```cs
public class Solution {
public int CountPalindromicSubsequence(string s) {
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.IndexOf(c), r = s.LastIndexOf(c);
int mask = 0;
for (int i = l + 1; i < r; ++i) {
int j = s[i] - 'a';
if ((mask >> j & 1) == 0) {
mask |= 1 << j;
++ans;
}
}
}
return ans;
}

return ans;
}
```

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

<!-- solution:start -->

### Solution 1
### Solution 1: Enumerate Both End Characters + Hash Table

Since the string contains only lowercase letters, we can directly enumerate all pairs of end characters. For each pair of end characters $c$, we find their first and last occurrence positions $l$ and $r$ in the string. If $r - l > 1$, it means we have found a palindromic subsequence that meets the conditions. We then count the number of unique characters between $[l+1,..r-1]$, which gives the number of palindromic subsequences with $c$ as the end characters, and add it to the answer.

After enumerating all pairs, we get the answer.

The time complexity is $O(n \times |\Sigma|)$, where $n$ is the length of the string and $\Sigma$ is the size of the character set. In this problem, $|\Sigma| = 26$. The space complexity is $O(|\Sigma|)$ or $O(1)$.

<!-- tabs:start -->

Expand All @@ -104,11 +110,14 @@ class Solution {
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.indexOf(c), r = s.lastIndexOf(c);
Set<Character> cs = new HashSet<>();
int mask = 0;
for (int i = l + 1; i < r; ++i) {
cs.add(s.charAt(i));
int j = s.charAt(i) - 'a';
if ((mask >> j & 1) == 0) {
mask |= 1 << j;
++ans;
}
}
ans += cs.size();
}
return ans;
}
Expand All @@ -124,9 +133,14 @@ public:
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.find_first_of(c), r = s.find_last_of(c);
unordered_set<char> cs;
for (int i = l + 1; i < r; ++i) cs.insert(s[i]);
ans += cs.size();
int mask = 0;
for (int i = l + 1; i < r; ++i) {
int j = s[i] - 'a';
if (mask >> j & 1 ^ 1) {
mask |= 1 << j;
++ans;
}
}
}
return ans;
}
Expand All @@ -139,80 +153,88 @@ public:
func countPalindromicSubsequence(s string) (ans int) {
for c := 'a'; c <= 'z'; c++ {
l, r := strings.Index(s, string(c)), strings.LastIndex(s, string(c))
cs := map[byte]struct{}{}
mask := 0
for i := l + 1; i < r; i++ {
cs[s[i]] = struct{}{}
j := int(s[i] - 'a')
if mask>>j&1 == 0 {
mask |= 1 << j
ans++
}
}
ans += len(cs)
}
return
}
```

#### C#

```cs
public class Solution {
public int CountPalindromicSubsequence(string s) {
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.IndexOf(c), r = s.LastIndexOf(c);
HashSet<char> cs = new HashSet<char>();
for (int i = l + 1; i < r; ++i) {
cs.Add(s[i]);
}
ans += cs.Count;
}
return ans;
}
}
```

#### TypeScript

```ts
export function countPalindromicSubsequence(s: string): number {
const cnt = new Map<string, [number, number]>();
const n = s.length;
function countPalindromicSubsequence(s: string): number {
let ans = 0;

for (let i = 0; i < n; i++) {
const ch = s[i];
if (cnt.has(ch)) cnt.get(ch)![1] = i;
else cnt.set(ch, [i, i]);
}

for (const [_, [i, j]] of cnt) {
if (i !== j) {
ans += new Set(s.slice(i + 1, j)).size;
const a = 'a'.charCodeAt(0);
for (let ch = 0; ch < 26; ++ch) {
const c = String.fromCharCode(ch + a);
const l = s.indexOf(c);
const r = s.lastIndexOf(c);
let mask = 0;
for (let i = l + 1; i < r; ++i) {
const j = s.charCodeAt(i) - a;
if (((mask >> j) & 1) ^ 1) {
mask |= 1 << j;
++ans;
}
}
}

return ans;
}
```

#### JavaScript

```js
export function countPalindromicSubsequence(s) {
const cnt = new Map();
const n = s.length;
/**
* @param {string} s
* @return {number}
*/
var countPalindromicSubsequence = function (s) {
let ans = 0;

for (let i = 0; i < n; i++) {
const ch = s[i];
if (cnt.has(ch)) cnt.get(ch)[1] = i;
else cnt.set(ch, [i, i]);
const a = 'a'.charCodeAt(0);
for (let ch = 0; ch < 26; ++ch) {
const c = String.fromCharCode(ch + a);
const l = s.indexOf(c);
const r = s.lastIndexOf(c);
let mask = 0;
for (let i = l + 1; i < r; ++i) {
const j = s.charCodeAt(i) - a;
if (((mask >> j) & 1) ^ 1) {
mask |= 1 << j;
++ans;
}
}
}
return ans;
};
```

#### C#

for (const [_, [i, j]] of cnt) {
if (i !== j) {
ans += new Set(s.slice(i + 1, j)).size;
```cs
public class Solution {
public int CountPalindromicSubsequence(string s) {
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.IndexOf(c), r = s.LastIndexOf(c);
int mask = 0;
for (int i = l + 1; i < r; ++i) {
int j = s[i] - 'a';
if ((mask >> j & 1) == 0) {
mask |= 1 << j;
++ans;
}
}
}
return ans;
}

return ans;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ class Solution {
int ans = 0;
for (char c = 'a'; c <= 'z'; ++c) {
int l = s.find_first_of(c), r = s.find_last_of(c);
unordered_set<char> cs;
for (int i = l + 1; i < r; ++i) cs.insert(s[i]);
ans += cs.size();
int mask = 0;
for (int i = l + 1; i < r; ++i) {
int j = s[i] - 'a';
if (mask >> j & 1 ^ 1) {
mask |= 1 << j;
++ans;
}
}
}
return ans;
}
};
};
Loading

0 comments on commit c6fa041

Please sign in to comment.