A string s is nice if, for every letter of the alphabet that s
contains, it appears both in uppercase and lowercase. For example,
"abABB" is nice because 'A' and 'a' appear, and 'B' and 'b' appear.
However, "abA" is not because 'b' appears, but 'B' does not.
Given a string s, return the longestsubstring of s that is nice.
If there are multiple, return the substring of the earliest occurrence. If there are none, return an empty string.
Input: s ="YazaAay"Output: "aAa"Explanation: "aAa"is a nice string because 'A/a'is the only letter of the alphabet in s, and both 'A' and 'a' appear."aAa"is the longest nice substring.
A substring is nice if for every character, both its lowercase and uppercase forms are present. If a character violates this, any nice substring must be fully on one side of it. We can recursively split on such characters.
If the string length is less than 2, return an empty string.
Build a set of all characters in the string.
For each character, if both its lowercase and uppercase forms are present, continue. Otherwise, split the string at this character and recursively solve both sides.
Return the longer nice substring found, or the leftmost if equal.
classSolution {
public String longestNiceSubstring(String s) {
if (s.length() < 2) return"";
Set<Character> st =new HashSet<>();
for (char c : s.toCharArray()) st.add(c);
for (int i = 0; i < s.length(); i++) {
if (st.contains(Character.toLowerCase(s.charAt(i))) && st.contains(Character.toUpperCase(s.charAt(i)))) continue;
String left = longestNiceSubstring(s.substring(0, i));
String right = longestNiceSubstring(s.substring(i+1));
return left.length() >= right.length() ? left : right;
}
return s;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
classSolution {
funlongestNiceSubstring(s: String): String {
if (s.length < 2) return""val st = s.toSet()
for (i in s.indices) {
if (st.contains(s[i].lowercaseChar()) && st.contains(s[i].uppercaseChar())) continueval left = longestNiceSubstring(s.substring(0, i))
val right = longestNiceSubstring(s.substring(i+1))
returnif (left.length >= right.length) left else right
}
return s
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
deflongestNiceSubstring(self, s: str) -> str:
if len(s) <2:
return"" st = set(s)
for i, c in enumerate(s):
if c.lower() in st and c.upper() in st:
continue left = self.longestNiceSubstring(s[:i])
right = self.longestNiceSubstring(s[i+1:])
return left if len(left) >= len(right) else right
return s
1
2
3
4
5
6
7
8
9
10
11
12
13
impl Solution {
pubfnlongest_nice_substring(s: String) -> String {
if s.len() <2 { return String::new(); }
let st: std::collections::HashSet<char>= s.chars().collect();
for (i, c) in s.chars().enumerate() {
if st.contains(&c.to_ascii_lowercase()) && st.contains(&c.to_ascii_uppercase()) { continue; }
let left = Solution::longest_nice_substring(s[..i].to_string());
let right = Solution::longest_nice_substring(s[i+1..].to_string());
returnif left.len() >= right.len() { left } else { right };
}
s
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
classSolution {
longestNiceSubstring(s: string):string {
if (s.length<2) return"";
constst=newSet(s);
for (leti=0; i<s.length; i++) {
if (st.has(s[i].toLowerCase()) &&st.has(s[i].toUpperCase())) continue;
constleft=this.longestNiceSubstring(s.slice(0, i));
constright=this.longestNiceSubstring(s.slice(i+1));
returnleft.length>=right.length?left : right;
}
returns;
}
}