azarasi / LeetCode 1763. 最长的美好子字符串

Created Tue, 01 Feb 2022 19:52:49 +0800 Modified Wed, 18 Sep 2024 14:00:22 +0000

当一个字符串 s  包含的每一种字母的大写和小写形式 同时  出现在 s  中,就称这个字符串  s  是 美好 字符串。比方说,"abABB"  是美好字符串,因为  'A' 和  'a'  同时出现了,且  'B' 和  'b'  也同时出现了。然而,"abA"  不是美好字符串因为  'b'  出现了,而  'B'  没有出现。

给你一个字符串  s ,请你返回  s  最长的  美好子字符串 。如果有多个答案,请你返回  最早  出现的一个。如果不存在美好子字符串,请你返回一个空字符串。

示例 1:

输入: s = “YazaAay”

输出: “aAa”

解释: “aAa” 是一个美好字符串,因为这个子串中仅含一种字母,其小写形式 ‘a’ 和大写形式 ‘A’ 也同时出现了。 “aAa” 是最长的美好子字符串。

示例 2:

输入: s = “Bb”

输出: “Bb”

解释: “Bb” 是美好字符串,因为 ‘B’ 和 ‘b’ 都出现了。整个字符串也是原字符串的子字符串。

示例 3:

输入: s = “c”

输出: ""

解释: 没有美好子字符串。

示例 4:

输入: s = “dDzeE”

输出: “dD”

解释: “dD” 和 “eE” 都是最长美好子字符串。 由于有多个美好子字符串,返回 “dD” ,因为它出现得最早。

提示:

  • 1 <= s.length <= 100
  • s  只包含大写和小写英文字母。
  • 穷举每个子串检查是否是美好字符串。

题解

由于字符串的长度比较小,因此可以枚举所有可能的子字符串,然后检测该字符串是否为美好的字符串,并得到长度最长的美好字符串。

  • 题目关于美好字符串的定义为: 字符串中的每个字母的大写和小写形式同时出现在该字符串中。检测时,由于英文字母 ‘a’−‘z’ 最多只有 26 个, 因此可以利用二进制位来进行标记,lower 标记字符中出现过小写英文字母,upper 标记字符中出现过大写英文字母。如果满足 lower=upper ,我们则认为字符串中所有的字符都满足大小写形式同时出现,则认定该字符串为美好字符串。

  • 题目要求如果有多个答案,返回在字符串中最早出现的那个。此时,只需要首先检测从以字符串索引 0 为起始的子字符串。

class Solution {
public:
    pair<int, int> dfs(string s, int start, int end) {
        if(start == end) {
            return {start, 0};
        }
        int lower     = 0;
        int upper     = 0;
        int max_start = 0;
        int max_len   = 0;
        for(int i = start; i <= end; i++) {
            char ch = s[i];
            if(islower(ch)) {
                lower |= 1 << (ch - 'a');
            } else {//isupper
                upper |= 1 << (ch - 'A');
            }
        }
        if(lower == upper) {//是美好字符串
            return {start, end - start + 1};
        }
        //不是美好字符串
        int not_nice = lower ^ upper;//无法构成美好字符串的字符
        int i        = start;
        while(i <= end) {
            if(((not_nice >> (tolower(s[i]) - 'a')) & 1) == 1) {//在not_nice中
                i++;
                continue;
            }
            int j = i + 1;
            while(j <= end && (((not_nice >> (tolower(s[j]) - 'a')) & 1) != 1)) {
                j++;
            }
            auto [next_start, next_len] = dfs(s, i, j - 1);
            if(max_len < next_len) {
                max_len   = next_len;
                max_start = next_start;
            }
            i = j;
        }
        return {max_start, max_len};
    }

    string longestNiceSubstring(string s) {
        auto [max_start, max_len] = dfs(s, 0, s.length() - 1);
        if(max_len == 0) {
            return "";
        }
        return s.substr(max_start, max_len);
    }
};