Skip to content

Commit 5804242

Browse files
committed
feat: add solutions to lc problem: No.0159
No.0159.Longest Substring with At Most Two Distinct Characters
1 parent bcd38ce commit 5804242

File tree

8 files changed

+161
-155
lines changed

8 files changed

+161
-155
lines changed

solution/0100-0199/0155.Min Stack/README.md

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ minStack.getMin(); --> 返回 -2.
5757

5858
**方法一:双栈**
5959

60-
我们用两个栈来实现,其中`stk1` 用来存储数据,`stk2` 用来存储当前栈中的最小值。初始时,`stk2` 中存储一个极大值。
60+
我们用两个栈来实现,其中 `stk1` 用来存储数据,`stk2` 用来存储当前栈中的最小值。初始时,`stk2` 中存储一个极大值。
6161

62-
- 当我们向栈中压入一个元素 `x` 时,我们将 `x` 压入 `stk1`,并将 `min(x, stk2[-1])` 压入 `stk2`
62+
- 当我们向栈中压入一个元素 $x$ 时,我们将 $x$ 压入 `stk1`,并将 `min(x, stk2[-1])` 压入 `stk2`
6363
- 当我们从栈中弹出一个元素时,我们将 `stk1``stk2` 的栈顶元素都弹出。
6464
- 当我们要获取当前栈中的栈顶元素时,我们只需要返回 `stk1` 的栈顶元素即可。
6565
- 当我们要获取当前栈中的最小值时,我们只需要返回 `stk2` 的栈顶元素即可。
6666

67-
时间复杂度:对于每个操作,时间复杂度均为 $O(1)$,空间复杂度 $O(n)$。
67+
每个操作的时间复杂度为 $O(1)$。整体的空间复杂度为 $O(n)$。
6868

6969
<!-- tabs:start -->
7070

@@ -74,31 +74,29 @@ minStack.getMin(); --&gt; 返回 -2.
7474

7575
```python
7676
class MinStack:
77+
7778
def __init__(self):
78-
"""
79-
initialize your data structure here.
80-
"""
81-
self.s = []
82-
self.mins = [inf]
79+
self.stk1 = []
80+
self.stk2 = [inf]
8381

84-
def push(self, val: int) -> None:
85-
self.s.append(val)
86-
self.mins.append(min(self.mins[-1], val))
82+
def push(self, x: int) -> None:
83+
self.stk1.append(x)
84+
self.stk2.append(min(x, self.stk2[-1]))
8785

8886
def pop(self) -> None:
89-
self.s.pop()
90-
self.mins.pop()
87+
self.stk1.pop()
88+
self.stk2.pop()
9189

9290
def top(self) -> int:
93-
return self.s[-1]
91+
return self.stk1[-1]
9492

9593
def getMin(self) -> int:
96-
return self.mins[-1]
94+
return self.stk2[-1]
9795

9896

9997
# Your MinStack object will be instantiated and called as such:
10098
# obj = MinStack()
101-
# obj.push(val)
99+
# obj.push(x)
102100
# obj.pop()
103101
# param_3 = obj.top()
104102
# param_4 = obj.getMin()

solution/0100-0199/0156.Binary Tree Upside Down/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656

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

59+
**方法一:递归**
60+
5961
若根节点为空,或者根节点左子树为空,直接返回根节点。
6062

6163
递归处理左子树,返回的根节点 newRoot,也就是二叉树上下翻转后的根节点。
@@ -64,6 +66,8 @@
6466

6567
接着将根节点 root 的左右子节点置为空,最后返回 newRoot 即可。
6668

69+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树节点个数。
70+
6771
<!-- tabs:start -->
6872

6973
### **Python3**

solution/0100-0199/0159.Longest Substring with At Most Two Distinct Characters/README.md

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@
3939

4040
<!-- 这里可写通用的实现逻辑 -->
4141

42-
哈希表 + 双指针。
42+
**方法一:哈希表 + 滑动窗口**
43+
44+
我们维护一个哈希表 `cnt` 记录当前滑动窗口中各个字符出现的次数,如果哈希表中的键值对个数超过 $2$,则说明当前滑动窗口中包含了超过 $2$ 个不同的字符,此时需要移动左指针 `j`,直到哈希表中的键值对个数不超过 $2$ 为止,然后更新窗口的最大长度。
45+
46+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
4347

4448
<!-- tabs:start -->
4549

@@ -50,17 +54,16 @@
5054
```python
5155
class Solution:
5256
def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int:
53-
mp = Counter()
54-
i = j = ans = 0
55-
for c in s:
56-
mp[c] += 1
57-
while len(mp) > 2:
58-
mp[s[i]] -= 1
59-
if mp[s[i]] == 0:
60-
mp.pop(s[i])
61-
i += 1
62-
ans = max(ans, j - i + 1)
63-
j += 1
57+
cnt = Counter()
58+
ans = j = 0
59+
for i, c in enumerate(s):
60+
cnt[c] += 1
61+
while len(cnt) > 2:
62+
cnt[s[j]] -= 1
63+
if cnt[s[j]] == 0:
64+
cnt.pop(s[j])
65+
j += 1
66+
ans = max(ans, i - j + 1)
6467
return ans
6568
```
6669

@@ -71,20 +74,20 @@ class Solution:
7174
```java
7275
class Solution {
7376
public int lengthOfLongestSubstringTwoDistinct(String s) {
74-
Map<Character, Integer> mp = new HashMap<>();
75-
int i = 0, j = 0, ans = 0;
76-
for (char c : s.toCharArray()) {
77-
mp.put(c, mp.getOrDefault(c, 0) + 1);
78-
while (mp.size() > 2) {
79-
char t = s.charAt(i);
80-
mp.put(t, mp.get(t) - 1);
81-
if (mp.get(t) == 0) {
82-
mp.remove(t);
77+
Map<Character, Integer> cnt = new HashMap<>();
78+
int n = s.length();
79+
int ans = 0;
80+
for (int i = 0, j = 0; i < n; ++i) {
81+
char c = s.charAt(i);
82+
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
83+
while (cnt.size() > 2) {
84+
char t = s.charAt(j++);
85+
cnt.put(t, cnt.get(t) - 1);
86+
if (cnt.get(t) == 0) {
87+
cnt.remove(t);
8388
}
84-
++i;
8589
}
86-
ans = Math.max(ans, j - i + 1);
87-
++j;
90+
ans = Math.max(ans, i - j + 1);
8891
}
8992
return ans;
9093
}
@@ -97,17 +100,19 @@ class Solution {
97100
class Solution {
98101
public:
99102
int lengthOfLongestSubstringTwoDistinct(string s) {
100-
unordered_map<char, int> mp;
101-
int i = 0, j = 0, ans = 0;
102-
for (char& c : s) {
103-
++mp[c];
104-
while (mp.size() > 2) {
105-
--mp[s[i]];
106-
if (mp[s[i]] == 0) mp.erase(s[i]);
107-
++i;
103+
unordered_map<char, int> cnt;
104+
int n = s.size();
105+
int ans = 0;
106+
for (int i = 0, j = 0; i < n; ++i) {
107+
cnt[s[i]]++;
108+
while (cnt.size() > 2) {
109+
cnt[s[j]]--;
110+
if (cnt[s[j]] == 0) {
111+
cnt.erase(s[j]);
112+
}
113+
++j;
108114
}
109-
ans = max(ans, j - i + 1);
110-
++j;
115+
ans = max(ans, i - j + 1);
111116
}
112117
return ans;
113118
}
@@ -117,22 +122,21 @@ public:
117122
### **Go**
118123
119124
```go
120-
func lengthOfLongestSubstringTwoDistinct(s string) int {
121-
mp := make(map[byte]int)
122-
i, j, ans := 0, 0, 0
123-
for _, c := range s {
124-
mp[byte(c)]++
125-
for len(mp) > 2 {
126-
mp[s[i]]--
127-
if mp[s[i]] == 0 {
128-
delete(mp, s[i])
125+
func lengthOfLongestSubstringTwoDistinct(s string) (ans int) {
126+
cnt := map[byte]int{}
127+
j := 0
128+
for i := range s {
129+
cnt[s[i]]++
130+
for len(cnt) > 2 {
131+
cnt[s[j]]--
132+
if cnt[s[j]] == 0 {
133+
delete(cnt, s[j])
129134
}
130-
i++
135+
j++
131136
}
132-
ans = max(ans, j-i+1)
133-
j++
137+
ans = max(ans, i-j+1)
134138
}
135-
return ans
139+
return
136140
}
137141
138142
func max(a, b int) int {

solution/0100-0199/0159.Longest Substring with At Most Two Distinct Characters/README_EN.md

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,16 @@
4040
```python
4141
class Solution:
4242
def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int:
43-
mp = Counter()
44-
i = j = ans = 0
45-
for c in s:
46-
mp[c] += 1
47-
while len(mp) > 2:
48-
mp[s[i]] -= 1
49-
if mp[s[i]] == 0:
50-
mp.pop(s[i])
51-
i += 1
52-
ans = max(ans, j - i + 1)
53-
j += 1
43+
cnt = Counter()
44+
ans = j = 0
45+
for i, c in enumerate(s):
46+
cnt[c] += 1
47+
while len(cnt) > 2:
48+
cnt[s[j]] -= 1
49+
if cnt[s[j]] == 0:
50+
cnt.pop(s[j])
51+
j += 1
52+
ans = max(ans, i - j + 1)
5453
return ans
5554
```
5655

@@ -59,20 +58,20 @@ class Solution:
5958
```java
6059
class Solution {
6160
public int lengthOfLongestSubstringTwoDistinct(String s) {
62-
Map<Character, Integer> mp = new HashMap<>();
63-
int i = 0, j = 0, ans = 0;
64-
for (char c : s.toCharArray()) {
65-
mp.put(c, mp.getOrDefault(c, 0) + 1);
66-
while (mp.size() > 2) {
67-
char t = s.charAt(i);
68-
mp.put(t, mp.get(t) - 1);
69-
if (mp.get(t) == 0) {
70-
mp.remove(t);
61+
Map<Character, Integer> cnt = new HashMap<>();
62+
int n = s.length();
63+
int ans = 0;
64+
for (int i = 0, j = 0; i < n; ++i) {
65+
char c = s.charAt(i);
66+
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
67+
while (cnt.size() > 2) {
68+
char t = s.charAt(j++);
69+
cnt.put(t, cnt.get(t) - 1);
70+
if (cnt.get(t) == 0) {
71+
cnt.remove(t);
7172
}
72-
++i;
7373
}
74-
ans = Math.max(ans, j - i + 1);
75-
++j;
74+
ans = Math.max(ans, i - j + 1);
7675
}
7776
return ans;
7877
}
@@ -85,17 +84,19 @@ class Solution {
8584
class Solution {
8685
public:
8786
int lengthOfLongestSubstringTwoDistinct(string s) {
88-
unordered_map<char, int> mp;
89-
int i = 0, j = 0, ans = 0;
90-
for (char& c : s) {
91-
++mp[c];
92-
while (mp.size() > 2) {
93-
--mp[s[i]];
94-
if (mp[s[i]] == 0) mp.erase(s[i]);
95-
++i;
87+
unordered_map<char, int> cnt;
88+
int n = s.size();
89+
int ans = 0;
90+
for (int i = 0, j = 0; i < n; ++i) {
91+
cnt[s[i]]++;
92+
while (cnt.size() > 2) {
93+
cnt[s[j]]--;
94+
if (cnt[s[j]] == 0) {
95+
cnt.erase(s[j]);
96+
}
97+
++j;
9698
}
97-
ans = max(ans, j - i + 1);
98-
++j;
99+
ans = max(ans, i - j + 1);
99100
}
100101
return ans;
101102
}
@@ -105,22 +106,21 @@ public:
105106
### **Go**
106107
107108
```go
108-
func lengthOfLongestSubstringTwoDistinct(s string) int {
109-
mp := make(map[byte]int)
110-
i, j, ans := 0, 0, 0
111-
for _, c := range s {
112-
mp[byte(c)]++
113-
for len(mp) > 2 {
114-
mp[s[i]]--
115-
if mp[s[i]] == 0 {
116-
delete(mp, s[i])
109+
func lengthOfLongestSubstringTwoDistinct(s string) (ans int) {
110+
cnt := map[byte]int{}
111+
j := 0
112+
for i := range s {
113+
cnt[s[i]]++
114+
for len(cnt) > 2 {
115+
cnt[s[j]]--
116+
if cnt[s[j]] == 0 {
117+
delete(cnt, s[j])
117118
}
118-
i++
119+
j++
119120
}
120-
ans = max(ans, j-i+1)
121-
j++
121+
ans = max(ans, i-j+1)
122122
}
123-
return ans
123+
return
124124
}
125125
126126
func max(a, b int) int {

solution/0100-0199/0159.Longest Substring with At Most Two Distinct Characters/Solution.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
class Solution {
22
public:
33
int lengthOfLongestSubstringTwoDistinct(string s) {
4-
unordered_map<char, int> mp;
5-
int i = 0, j = 0, ans = 0;
6-
for (char& c : s) {
7-
++mp[c];
8-
while (mp.size() > 2) {
9-
--mp[s[i]];
10-
if (mp[s[i]] == 0) mp.erase(s[i]);
11-
++i;
4+
unordered_map<char, int> cnt;
5+
int n = s.size();
6+
int ans = 0;
7+
for (int i = 0, j = 0; i < n; ++i) {
8+
cnt[s[i]]++;
9+
while (cnt.size() > 2) {
10+
cnt[s[j]]--;
11+
if (cnt[s[j]] == 0) {
12+
cnt.erase(s[j]);
13+
}
14+
++j;
1215
}
13-
ans = max(ans, j - i + 1);
14-
++j;
16+
ans = max(ans, i - j + 1);
1517
}
1618
return ans;
1719
}

0 commit comments

Comments
 (0)