跳转至

3628. 插入一个字母的最大子序列数

题目描述

给你一个由大写英文字母组成的字符串 s

你可以在字符串的 任意 位置(包括字符串的开头或结尾)最多插入一个 大写英文字母。

返回在 最多插入一个字母 后,字符串中可以形成的 "LCT" 子序列的 最大 数量。

子序列 是从另一个字符串中删除某些字符(可以不删除)且不改变剩余字符顺序后得到的一个 非空 字符串。

 

示例 1:

输入: s = "LMCT"

输出: 2

解释:

可以在字符串 s 的开头插入一个 "L",变为 "LLMCT",其中包含 2 个子序列,分别位于下标 [0, 3, 4] 和 [1, 3, 4]。

示例 2:

输入: s = "LCCT"

输出: 4

解释:

可以在字符串 s 的开头插入一个 "L",变为 "LLCCT",其中包含 4 个子序列,分别位于下标 [0, 2, 4]、[0, 3, 4]、[1, 2, 4] 和 [1, 3, 4]。

示例 3:

输入: s = "L"

输出: 0

解释:

插入一个字母无法获得子序列 "LCT",结果为 0。

 

提示:

  • 1 <= s.length <= 105
  • s 仅由大写英文字母组成。

解法

方法一:枚举

我们可以先计算出原字符串中 "LCT" 的子序列数量,然后考虑插入一个字母的情况。

计算 "LCT" 子序列的数量可以通过遍历字符串来实现。我们可以枚举中间的 "C",用两个变量 \(l\)\(r\) 分别维护左右两侧的 "L" 和 "T" 的数量。对于每个 "C",我们可以计算出它左侧的 "L" 的数量和右侧的 "T" 的数量,从而得到以该 "C" 为中间的 "LCT" 子序列数量为 \(l \times r\),累加到总数中。

接下来,我们需要考虑插入一个字母的情况。考虑到插入一个 "L" 或 "C" 或 "T" 的情况:

  • 插入一个 "L",那么我们只需要统计原字符串中 "CT" 的子序列数量。
  • 插入一个 "T",那么我们只需要统计原字符串中 "LC" 的子序列数量。
  • 插入一个 "C",那么我们只需要统计原字符串中 "LT" 的子序列数量,这种情况下,我们可以在前面枚举的过程中,维护一个变量 \(\textit{mx}\),表示当前最大的 \(l \times r\) 的值。

最后,我们将原字符串中 "LCT" 的子序列数量加上插入一个字母后的最大子序列数量,得到最终结果。

时间复杂度 \(O(n)\),其中 \(n\) 是字符串的长度。空间复杂度 \(O(1)\)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution:
    def numOfSubsequences(self, s: str) -> int:
        def calc(t: str) -> int:
            cnt = a = 0
            for c in s:
                if c == t[1]:
                    cnt += a
                a += int(c == t[0])
            return cnt

        l, r = 0, s.count("T")
        ans = mx = 0
        for c in s:
            r -= int(c == "T")
            if c == "C":
                ans += l * r
            l += int(c == "L")
            mx = max(mx, l * r)
        mx = max(mx, calc("LC"), calc("CT"))
        ans += mx
        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
class Solution {
    private char[] s;

    public long numOfSubsequences(String S) {
        s = S.toCharArray();
        int l = 0, r = 0;
        for (char c : s) {
            if (c == 'T') {
                ++r;
            }
        }
        long ans = 0, mx = 0;
        for (char c : s) {
            r -= c == 'T' ? 1 : 0;
            if (c == 'C') {
                ans += 1L * l * r;
            }
            l += c == 'L' ? 1 : 0;
            mx = Math.max(mx, 1L * l * r);
        }
        mx = Math.max(mx, Math.max(calc("LC"), calc("CT")));
        ans += mx;
        return ans;
    }

    private long calc(String t) {
        long cnt = 0;
        int a = 0;
        for (char c : s) {
            if (c == t.charAt(1)) {
                cnt += a;
            }
            a += c == t.charAt(0) ? 1 : 0;
        }
        return cnt;
    }
}
 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
class Solution {
public:
    long long numOfSubsequences(string s) {
        auto calc = [&](string t) {
            long long cnt = 0, a = 0;
            for (char c : s) {
                if (c == t[1]) {
                    cnt += a;
                }
                a += (c == t[0]);
            }
            return cnt;
        };

        long long l = 0, r = count(s.begin(), s.end(), 'T');
        long long ans = 0, mx = 0;
        for (char c : s) {
            r -= (c == 'T');
            if (c == 'C') {
                ans += l * r;
            }
            l += (c == 'L');
            mx = max(mx, l * r);
        }
        mx = max(mx, calc("LC"));
        mx = max(mx, calc("CT"));
        ans += mx;
        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
func numOfSubsequences(s string) int64 {
    calc := func(t string) int64 {
        cnt, a := int64(0), int64(0)
        for _, c := range s {
            if c == rune(t[1]) {
                cnt += a
            }
            if c == rune(t[0]) {
                a++
            }
        }
        return cnt
    }

    l, r := int64(0), int64(0)
    for _, c := range s {
        if c == 'T' {
            r++
        }
    }

    ans, mx := int64(0), int64(0)
    for _, c := range s {
        if c == 'T' {
            r--
        }
        if c == 'C' {
            ans += l * r
        }
        if c == 'L' {
            l++
        }
        mx = max(mx, l*r)
    }
    mx = max(mx, calc("LC"), calc("CT"))
    ans += mx
    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
function numOfSubsequences(s: string): number {
    const calc = (t: string): number => {
        let [cnt, a] = [0, 0];
        for (const c of s) {
            if (c === t[1]) cnt += a;
            if (c === t[0]) a++;
        }
        return cnt;
    };

    let [l, r] = [0, 0];
    for (const c of s) {
        if (c === 'T') r++;
    }

    let [ans, mx] = [0, 0];
    for (const c of s) {
        if (c === 'T') r--;
        if (c === 'C') ans += l * r;
        if (c === 'L') l++;
        mx = Math.max(mx, l * r);
    }

    mx = Math.max(mx, calc('LC'));
    mx = Math.max(mx, calc('CT'));
    ans += mx;
    return ans;
}

评论