Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ff8b3e9

Browse files
Update
1 parent 648df89 commit ff8b3e9

19 files changed

+508
-130
lines changed

‎problems/0015.三数之和.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
# 思路
3131

32+
针对本题,我录制了视频讲解:[梦破碎的地方!| LeetCode:15.三数之和](https://www.bilibili.com/video/BV1GW4y127qo),结合本题解一起看,事半功倍!
33+
3234
**注意[0, 0, 0, 0] 这组数据**
3335

3436
## 哈希解法

‎problems/0018.四数之和.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
# 思路
3131

32+
针对本题,我录制了视频讲解:[难在去重和剪枝!| LeetCode:18. 四数之和](https://www.bilibili.com/video/BV1DS4y147US),结合本题解一起看,事半功倍!
33+
3234
四数之和,和[15.三数之和](https://programmercarl.com/0015.三数之和.html)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://programmercarl.com/0015.三数之和.html) 的基础上再套一层for循环。
3335

3436
但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。比如:数组是`[-4, -3, -2, -1]`,`target``-10`,不能因为`-4 > -10`而跳过。但是我们依旧可以去做剪枝,逻辑变成`nums[i] > target && (nums[i] >=0 || target >= 0)`就可以了。

‎problems/0027.移除元素.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
## 思路
3030

31-
[本题B站视频讲解](https://www.bilibili.com/video/BV12A4y1Z7LP)
31+
针对本题,我录制了视频讲解:[数组中移除元素并不容易!LeetCode:27. 移除元素](https://www.bilibili.com/video/BV12A4y1Z7LP),结合本题解一起看,事半功倍!
3232

3333
有的同学可能说了,多余的元素,删掉不就得了。
3434

‎problems/0059.螺旋矩阵II.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
## 思路
2626

27-
为了利于录友们理解,我特意录制了视频,[拿下螺旋矩阵,《代码随想录》第五题!](https://www.bilibili.com/video/BV1SL4y1N7mV),结合本篇文章一起看,效果更佳。
27+
为了利于录友们理解,我特意录制了视频,[拿下螺旋矩阵!LeetCode:59.螺旋矩阵II](https://www.bilibili.com/video/BV1SL4y1N7mV),结合视频一起看,事半功倍!
2828

2929
这道题目可以说在面试中出现频率较高的题目,**本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。**
3030

‎problems/0134.加油站.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,9 @@ public:
7777
};
7878
```
7979
80-
* 时间复杂度:$O(n^2)$
81-
* 空间复杂度:$O(1)$
80+
* 时间复杂度:O(n^2)
81+
* 空间复杂度:O(1)
8282
83-
C++暴力解法在leetcode上提交也可以过。
8483
8584
## 贪心算法(方法一)
8685

‎problems/0151.翻转字符串里的单词.md

Lines changed: 33 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131

3232
# 思路
3333

34-
**这道题目可以说是综合考察了字符串的多种操作。**
34+
针对本题,我录制了视频讲解:[字符串复杂操作拿捏了! | LeetCode:151.翻转字符串里的单词](https://www.bilibili.com/video/BV1uT41177fX),结合本题解一起看,事半功倍!
3535

36+
**这道题目可以说是综合考察了字符串的多种操作。**
3637

3738
一些同学会使用split库函数,分隔单词,然后定义一个新的string字符串,最后再把单词倒序相加,那么这道题题目就是一道水题了,失去了它的意义。
3839

@@ -81,17 +82,14 @@ void removeExtraSpaces(string& s) {
8182
8283
如果不仔细琢磨一下erase的时间复杂度,还以为以上的代码是O(n)的时间复杂度呢。
8384
84-
想一下真正的时间复杂度是多少,一个erase本来就是O(n)的操作,erase实现原理题目:[数组:就移除个元素很难么?](https://programmercarl.com/0027.移除元素.html),最优的算法来移除元素也要O(n)
85+
想一下真正的时间复杂度是多少,一个erase本来就是O(n)的操作。
8586
8687
erase操作上面还套了一个for循环,那么以上代码移除冗余空格的代码时间复杂度为O(n^2)。
8788
8889
那么使用双指针法来去移除空格,最后resize(重新设置)一下字符串的大小,就可以做到O(n)的时间复杂度。
8990
90-
如果对这个操作比较生疏了,可以再看一下这篇文章:[数组:就移除个元素很难么?](https://programmercarl.com/0027.移除元素.html)是如何移除元素的。
91-
92-
那么使用双指针来移除冗余空格代码如下: fastIndex走的快,slowIndex走的慢,最后slowIndex就标记着移除多余空格后新字符串的长度。
93-
9491
```CPP
92+
//版本一
9593
void removeExtraSpaces(string& s) {
9694
int slowIndex = 0, fastIndex = 0; // 定义快指针,慢指针
9795
// 去掉字符串前面的空格
@@ -121,120 +119,58 @@ void removeExtraSpaces(string& s) {
121119
1. leetcode上的测试集里,字符串的长度不够长,如果足够长,性能差距会非常明显。
122120
2. leetcode的测程序耗时不是很准确的。
123121

124-
此时我们已经实现了removeExtraSpaces函数来移除冗余空格。
122+
版本一的代码是比较如何一般思考过程,就是 先移除字符串钱的空格,在移除中间的,在移除后面部分。
125123

126-
还做实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[344.反转字符串](https://programmercarl.com/0344.反转字符串.html)[541.反转字符串II](https://programmercarl.com/0541.反转字符串II.html)里已经讲过了。
124+
不过其实还可以优化,这部分和[27.移除元素](https://programmercarl.com/0027.移除元素.html)的逻辑是一样一样的,本题是移除空格,而 27.移除元素 就是移除元素。
127125

128-
代码如下:
126+
所以代码可以写的很精简,大家可以看 如下 代码 removeExtraSpaces 函数的实现:
129127

130-
```
131-
// 反转字符串s中左闭又闭的区间[start, end]
132-
void reverse(string& s, int start, int end) {
133-
for (int i = start, j = end; i < j; i++, j--) {
134-
swap(s[i], s[j]);
128+
```CPP
129+
// 版本二
130+
void removeExtraSpaces(string& s) {//去除所有空格并在相邻单词之间添加空格, 快慢指针。
131+
int slow = 0; //整体思想参考https://programmercarl.com/0027.移除元素.html
132+
for (int i = 0; i < s.size(); ++i) { //
133+
if (s[i] != ' ') { //遇到非空格就处理,即删除所有空格。
134+
if (slow != 0) s[slow++] = ' '; //手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。
135+
while (i < s.size() && s[i] != ' ') { //补上该单词,遇到空格说明单词结束。
136+
s[slow++] = s[i++];
137+
}
138+
}
135139
}
140+
s.resize(slow); //slow的大小即为去除多余空格后的大小。
136141
}
137142
```
138143
139-
本题C++整体代码
144+
如果以上代码看不懂,建议先把 [27.移除元素](https://programmercarl.com/0027.移除元素.html)这道题目做了,或者看视频讲解:[数组中移除元素并不容易!LeetCode:27. 移除元素](https://www.bilibili.com/video/BV12A4y1Z7LP) 。
140145
146+
此时我们已经实现了removeExtraSpaces函数来移除冗余空格。
141147
142-
```CPP
143-
// 版本一
144-
class Solution {
145-
public:
146-
// 反转字符串s中左闭又闭的区间[start, end]
147-
void reverse(string& s, int start, int end) {
148-
for (int i = start, j = end; i < j; i++, j--) {
149-
swap(s[i], s[j]);
150-
}
151-
}
148+
还做实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[344.反转字符串](https://programmercarl.com/0344.反转字符串.html)和[541.反转字符串II](https://programmercarl.com/0541.反转字符串II.html)里已经讲过了。
152149
153-
// 移除冗余空格:使用双指针(快慢指针法)O(n)的算法
154-
void removeExtraSpaces(string& s) {
155-
int slowIndex = 0, fastIndex = 0; // 定义快指针,慢指针
156-
// 去掉字符串前面的空格
157-
while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
158-
fastIndex++;
159-
}
160-
for (; fastIndex < s.size(); fastIndex++) {
161-
// 去掉字符串中间部分的冗余空格
162-
if (fastIndex - 1 > 0
163-
&& s[fastIndex - 1] == s[fastIndex]
164-
&& s[fastIndex] == ' ') {
165-
continue;
166-
} else {
167-
s[slowIndex++] = s[fastIndex];
168-
}
169-
}
170-
if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') { // 去掉字符串末尾的空格
171-
s.resize(slowIndex - 1);
172-
} else {
173-
s.resize(slowIndex); // 重新设置字符串大小
174-
}
175-
}
150+
代码如下:
176151
177-
string reverseWords(string s) {
178-
removeExtraSpaces(s); // 去掉冗余空格
179-
reverse(s, 0, s.size() - 1); // 将字符串全部反转
180-
int start = 0; // 反转的单词在字符串里起始位置
181-
int end = 0; // 反转的单词在字符串里终止位置
182-
bool entry = false; // 标记枚举字符串的过程中是否已经进入了单词区间
183-
for (int i = 0; i < s.size(); i++) { // 开始反转单词
184-
if (!entry) {
185-
start = i; // 确定单词起始位置
186-
entry = true; // 进入单词区间
187-
}
188-
// 单词后面有空格的情况,空格就是分词符
189-
if (entry && s[i] == ' ' && s[i - 1] != ' ') {
190-
end = i - 1; // 确定单词终止位置
191-
entry = false; // 结束单词区间
192-
reverse(s, start, end);
193-
}
194-
// 最后一个结尾单词之后没有空格的情况
195-
if (entry && (i == (s.size() - 1)) && s[i] != ' ' ) {
196-
end = i;// 确定单词终止位置
197-
entry = false; // 结束单词区间
198-
reverse(s, start, end);
199-
}
200-
}
201-
return s;
202-
}
203-
204-
// 当然这里的主函数reverseWords写的有一些冗余的,可以精简一些,精简之后的主函数为:
205-
/* 主函数简单写法
206-
string reverseWords(string s) {
207-
removeExtraSpaces(s);
208-
reverse(s, 0, s.size() - 1);
209-
for(int i = 0; i < s.size(); i++) {
210-
int j = i;
211-
// 查找单词间的空格,翻转单词
212-
while(j < s.size() && s[j] != ' ') j++;
213-
reverse(s, i, j - 1);
214-
i = j;
215-
}
216-
return s;
152+
```CPP
153+
// 反转字符串s中左闭又闭的区间[start, end]
154+
void reverse(string& s, int start, int end) {
155+
for (int i = start, j = end; i < j; i++, j--) {
156+
swap(s[i], s[j]);
217157
}
218-
*/
219-
};
158+
}
220159
```
221160

222-
效率:
223-
<img src='https://code-thinking.cdn.bcebos.com/pics/151_翻转字符串里的单词.png' width=600> </img></div>
161+
整体代码如下:
224162

225163
```CPP
226-
//版本二:
227-
//原理同版本1,更简洁实现。
228164
class Solution {
229165
public:
230-
void reverse(string& s, int start, int end){ //翻转,区间写法:闭区间 []
166+
void reverse(string& s, int start, int end){ //翻转,区间写法:左闭又闭 []
231167
for (int i = start, j = end; i < j; i++, j--) {
232168
swap(s[i], s[j]);
233169
}
234170
}
235171

236172
void removeExtraSpaces(string& s) {//去除所有空格并在相邻单词之间添加空格, 快慢指针。
237-
int slow = 0; //整体思想参考Leetcode: 27. 移除元素:https://leetcode.cn/problems/remove-element/
173+
int slow = 0; //整体思想参考https://programmercarl.com/0027.移除元素.html
238174
for (int i = 0; i < s.size(); ++i) { //
239175
if (s[i] != ' ') { //遇到非空格就处理,即删除所有空格。
240176
if (slow != 0) s[slow++] = ' '; //手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。
@@ -261,6 +197,7 @@ public:
261197
};
262198
```
263199
200+
264201
## 其他语言版本
265202
266203

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /