Skip to content

Commit 28f3d2a

Browse files
committed
feat: add solutions to lc problem: No.1763
No.1763.Longest Nice Substring
1 parent 9a19e89 commit 28f3d2a

File tree

6 files changed

+348
-102
lines changed

6 files changed

+348
-102
lines changed

solution/1700-1799/1763.Longest Nice Substring/README.md

Lines changed: 167 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,42 @@
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
**方法一:枚举 + 哈希表**
60+
61+
我们可以直接枚举所有子串的起点位置 $i$,找到以该位置所在的字符为首字符的所有子串,用哈希表 $s$ 记录子串的所有字符。
62+
63+
如果子串中存在一个字母找不到对应的大写字母或者小写字母,那么不满足条件,否则取最长的且最早出现的子串。
64+
65+
时间复杂度 $O(n^2 \times C)$,空间复杂度 $O(C)$。其中 $n$ 为字符串 $s$ 的长度,而 $C$ 为字符集的大小。
66+
67+
**方法二:枚举 + 位运算**
68+
69+
与方法一类似,我们可以直接枚举所有子串的起点位置 $i$,找到以该位置所在的字符为首字符的所有子串,用两个整数 $lower$ 和 $upper$ 分别记录子串中小写字母和大写字母的出现情况。
70+
71+
判断子串是否满足条件,只需要判断 $lower$ 和 $upper$ 中对应的位是否都为 $1$ 即可。
72+
73+
时间复杂度 $O(n^2)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
74+
5975
<!-- tabs:start -->
6076

6177
### **Python3**
6278

6379
<!-- 这里可写当前语言的特殊实现逻辑 -->
6480

81+
```python
82+
class Solution:
83+
def longestNiceSubstring(self, s: str) -> str:
84+
n = len(s)
85+
ans = ''
86+
for i in range(n):
87+
ss = set()
88+
for j in range(i, n):
89+
ss.add(s[j])
90+
if all(c.lower() in ss and c.upper() in ss for c in ss) and len(ans) < j - i + 1:
91+
ans = s[i: j + 1]
92+
return ans
93+
```
94+
6595
```python
6696
class Solution:
6797
def longestNiceSubstring(self, s: str) -> str:
@@ -74,8 +104,8 @@ class Solution:
74104
lower |= 1 << (ord(s[j]) - ord('a'))
75105
else:
76106
upper |= 1 << (ord(s[j]) - ord('A'))
77-
if lower == upper and j - i + 1 > len(ans):
78-
ans = s[i : j + 1]
107+
if lower == upper and len(ans) < j - i + 1:
108+
ans = s[i: j + 1]
79109
return ans
80110
```
81111

@@ -85,10 +115,39 @@ class Solution:
85115

86116
```java
87117
class Solution {
118+
public String longestNiceSubstring(String s) {
119+
int n = s.length();
120+
int k = -1;
121+
int mx = 0;
122+
for (int i = 0; i < n; ++i) {
123+
Set<Character> ss = new HashSet<>();
124+
for (int j = i; j < n; ++j) {
125+
ss.add(s.charAt(j));
126+
boolean ok = true;
127+
for (char a : ss) {
128+
char b = (char) (a ^ 32);
129+
if (!(ss.contains(a) && ss.contains(b))) {
130+
ok = false;
131+
break;
132+
}
133+
}
134+
if (ok && mx < j - i + 1) {
135+
mx = j - i + 1;
136+
k = i;
137+
}
138+
}
139+
}
140+
return k == -1 ? "" : s.substring(k, k + mx);
141+
}
142+
}
143+
```
88144

145+
```java
146+
class Solution {
89147
public String longestNiceSubstring(String s) {
90148
int n = s.length();
91-
String ans = "";
149+
int k = -1;
150+
int mx = 0;
92151
for (int i = 0; i < n; ++i) {
93152
int lower = 0, upper = 0;
94153
for (int j = i; j < n; ++j) {
@@ -98,82 +157,149 @@ class Solution {
98157
} else {
99158
upper |= 1 << (c - 'A');
100159
}
101-
if (lower == upper && j - i + 1 > ans.length()) {
102-
ans = s.substring(i, j + 1);
160+
if (lower == upper && mx < j - i + 1) {
161+
mx = j - i + 1;
162+
k = i;
103163
}
104164
}
105165
}
106-
return ans;
166+
return k == -1 ? "" : s.substring(k, k + mx);
107167
}
108168
}
109169
```
110170

111-
### **TypeScript**
171+
### **C++**
112172

113-
```ts
114-
function longestNiceSubstring(s: string): string {
115-
const n = s.length;
116-
let ans = '';
117-
for (let i = 0; i < n; i++) {
118-
let lower = 0,
119-
upper = 0;
120-
for (let j = i; j < n; j++) {
121-
const c = s.charCodeAt(j);
122-
if (c > 96) {
123-
lower |= 1 << (c - 97);
124-
} else {
125-
upper |= 1 << (c - 65);
126-
}
127-
if (lower == upper && j - i + 1 > ans.length) {
128-
ans = s.substring(i, j + 1);
173+
```cpp
174+
class Solution {
175+
public:
176+
string longestNiceSubstring(string s) {
177+
int n = s.size();
178+
int k = -1, mx = 0;
179+
for (int i = 0; i < n; ++i) {
180+
unordered_set<char> ss;
181+
for (int j = i; j < n; ++j) {
182+
ss.insert(s[j]);
183+
bool ok = true;
184+
for (auto& a : ss) {
185+
char b = a ^ 32;
186+
if (!(ss.count(a) && ss.count(b))) {
187+
ok = false;
188+
break;
189+
}
190+
}
191+
if (ok && mx < j - i + 1) {
192+
mx = j - i + 1;
193+
k = i;
194+
}
129195
}
130196
}
197+
return k == -1 ? "" : s.substr(k, mx);
131198
}
132-
return ans;
133-
}
199+
};
134200
```
135201
136-
### **C++**
137-
138202
```cpp
139203
class Solution {
140204
public:
141205
string longestNiceSubstring(string s) {
142206
int n = s.size();
143-
string ans = "";
207+
int k = -1, mx = 0;
144208
for (int i = 0; i < n; ++i) {
145209
int lower = 0, upper = 0;
146210
for (int j = i; j < n; ++j) {
147-
if (islower(s[j]))
148-
lower |= 1 << (s[j] - 'a');
149-
else
150-
upper |= 1 << (s[j] - 'A');
151-
if (lower == upper && j - i + 1 > ans.size()) ans = s.substr(i, j - i + 1);
211+
char c = s[j];
212+
if (islower(c)) lower |= 1 << (c - 'a');
213+
else upper |= 1 << (c - 'A');
214+
if (lower == upper && mx < j - i + 1) {
215+
mx = j - i + 1;
216+
k = i;
217+
}
152218
}
153219
}
154-
return ans;
220+
return k == -1 ? "" : s.substr(k, mx);
155221
}
156222
};
157223
```
158224

159225
### **Go**
160226

161227
```go
162-
func longestNiceSubstring(s string) (ans string) {
163-
for i := range s {
164-
lower, upper := 0, 0
165-
for j := i; j < len(s); j++ {
228+
func longestNiceSubstring(s string) string {
229+
n := len(s)
230+
k, mx := -1, 0
231+
for i := 0; i < n; i++ {
232+
ss := map[byte]bool{}
233+
for j := i; j < n; j++ {
234+
ss[s[j]] = true
235+
ok := true
236+
for a := range ss {
237+
b := a ^ 32
238+
if !(ss[a] && ss[b]) {
239+
ok = false
240+
break
241+
}
242+
}
243+
if ok && mx < j-i+1 {
244+
mx = j - i + 1
245+
k = i
246+
}
247+
}
248+
}
249+
if k < 0 {
250+
return ""
251+
}
252+
return s[k : k+mx]
253+
}
254+
```
255+
256+
```go
257+
func longestNiceSubstring(s string) string {
258+
n := len(s)
259+
k, mx := -1, 0
260+
for i := 0; i < n; i++ {
261+
var lower, upper int
262+
for j := i; j < n; j++ {
166263
if unicode.IsLower(rune(s[j])) {
167264
lower |= 1 << (s[j] - 'a')
168265
} else {
169266
upper |= 1 << (s[j] - 'A')
170267
}
171-
if lower == upper && j-i+1 > len(ans) {
172-
ans = s[i : j+1]
268+
if lower == upper && mx < j-i+1 {
269+
mx = j - i + 1
270+
k = i
173271
}
174272
}
175273
}
176-
return
274+
if k < 0 {
275+
return ""
276+
}
277+
return s[k : k+mx]
278+
}
279+
```
280+
281+
### **TypeScript**
282+
283+
```ts
284+
function longestNiceSubstring(s: string): string {
285+
const n = s.length;
286+
let ans = '';
287+
for (let i = 0; i < n; i++) {
288+
let lower = 0,
289+
upper = 0;
290+
for (let j = i; j < n; j++) {
291+
const c = s.charCodeAt(j);
292+
if (c > 96) {
293+
lower |= 1 << (c - 97);
294+
} else {
295+
upper |= 1 << (c - 65);
296+
}
297+
if (lower == upper && j - i + 1 > ans.length) {
298+
ans = s.substring(i, j + 1);
299+
}
300+
}
301+
}
302+
return ans;
177303
}
178304
```
179305

0 commit comments

Comments
 (0)