Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 141cccb

Browse files
Update
1 parent 1c4ab01 commit 141cccb

File tree

7 files changed

+233
-30
lines changed

7 files changed

+233
-30
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
* [本周小结!(回溯算法系列一)](https://mp.weixin.qq.com/s/m2GnTJdkYhAamustbb6lmw)
139139
* [回溯算法:求组合总和(二)](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)
140140
* [回溯算法:求组合总和(三)](https://mp.weixin.qq.com/s/_1zPYk70NvHsdY8UWVGXmQ)
141+
* [回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)
141142

142143
(持续更新中....)
143144

@@ -336,6 +337,7 @@
336337
|[0113.路径总和II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0113.路径总和II.md) |二叉树树 |简单|**深度优先搜索/递归** **回溯** ****|
337338
|[0116.填充每个节点的下一个右侧节点指针](https://github.com/youngyangyang04/leetcode/blob/master/problems/0116.填充每个节点的下一个右侧节点指针.md) |二叉树 |中等|**递归** **迭代/广度优先搜索**|
338339
|[0117.填充每个节点的下一个右侧节点指针II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0117.填充每个节点的下一个右侧节点指针II.md) |二叉树 |中等|**递归** **迭代/广度优先搜索**|
340+
|[0127.单词接龙](https://github.com/youngyangyang04/leetcode/blob/master/problems/ 0127.单词接龙.md) |广度优先搜索 |中等|**广度优先搜索**|
339341
|[0129.求根到叶子节点数字之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0129.求根到叶子节点数字之和.md) |二叉树 |中等|**递归/回溯** 递归里隐藏着回溯,和113.路径总和II类似|
340342
|[0131.分割回文串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0131.分割回文串.md) |回溯 |中等|**回溯**|
341343
|[0141.环形链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0141.环形链表.md) |链表 |简单|**快慢指针/双指针**|
@@ -377,6 +379,7 @@
377379
|[0434.字符串中的单词数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0434.字符串中的单词数.md) |字符串 |简单|**模拟**|
378380
|[0450.删除二叉搜索树中的节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/0450.删除二叉搜索树中的节点.md) ||中等|**递归**|
379381
|[0454.四数相加II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0454.四数相加II.md) |哈希表 |中等| **哈希**|
382+
|[0455.分发饼干](https://github.com/youngyangyang04/leetcode/blob/master/problems/0455.分发饼干.md) |贪心 |简单| **贪心**|
380383
|[0459.重复的子字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0459.重复的子字符串.md) |字符创 |简单| **KMP**|
381384
|[0486.预测赢家](https://github.com/youngyangyang04/leetcode/blob/master/problems/0486.预测赢家.md) |动态规划 |中等| **递归** **记忆递归** **动态规划**|
382385
|[0491.递增子序列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0491.递增子序列.md) |深度优先搜索 |中等|**深度优先搜索/回溯算法**|

pics/127.单词接龙.png

45.2 KB
Loading

pics/455.分发饼干.png

34.5 KB
Loading

problems/0057.插入区间.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11

2+
# 链接
3+
https://leetcode-cn.com/problems/insert-interval/
4+
5+
# 思路
26
这道题目合并的情况有很多种,想想都让人头疼。
37

48
我把这道题目化为三步:

problems/0093.复原IP地址.md

Lines changed: 111 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
## 题目地址
2-
https://leetcode-cn.com/problems/restore-ip-addresses/
32

4-
# 93. 复原IP地址
3+
> 一些录友表示跟不上现在的节奏,想从头开始打卡学习起来,可以在公众号左下方,「算法汇总」可以找到历史文章,都是按系列排好顺序的,挨个看就可以了,看文章下的留言你就会发现,有很多录友都在从头打卡,你并不孤单!
4+
5+
# 93.复原IP地址
6+
7+
题目地址:https://leetcode-cn.com/problems/restore-ip-addresses/
58

69
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
710

811
有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
912

1013
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效的 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效的 IP 地址。
1114

12-
 
13-
14-
示例 1:
15+
示例 1:
1516
输入:s = "25525511135"
1617
输出:["255.255.11.135","255.255.111.35"]
1718

@@ -36,17 +37,44 @@ https://leetcode-cn.com/problems/restore-ip-addresses/
3637
s 仅由数字组成
3738

3839

39-
## 思路
40+
# 思路
41+
42+
做这道题目之前,最好先把[回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)这个做了。
4043

41-
这道题目相信大家刚看时看到的时候,应该会一脸茫然。
44+
这道题目相信大家刚看的时候,应该会一脸茫然。
4245

43-
那么只要意识到这是切割问题,那么切割问题就可以使用回溯搜索法把所有可能性搜出来,和[0131.分割回文串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0131.分割回文串.md) 类似
46+
其实只要意识到这是切割问题,**切割问题就可以使用回溯搜索法把所有可能性搜出来**,和刚做过的[回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)就十分类似了
4447

45-
那么切割问题可以抽象为树型结构,如图:
48+
切割问题可以抽象为树型结构,如图:
4649

4750
<img src='../pics/93.复原IP地址.png' width=600> </img></div>
4851

49-
终止条件: 和[0131.分割回文串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0131.分割回文串.md) 不同,本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。
52+
53+
## 回溯三部曲
54+
55+
* 递归参数
56+
57+
[回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)中我们就提到切割问题类似组合问题。
58+
59+
startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置。
60+
61+
本题我们还需要一个变量pointNum,记录添加逗点的数量。
62+
63+
所以代码如下:
64+
65+
```
66+
vector<string> result;// 记录结果
67+
// startIndex: 搜索的起始位置,pointNum:添加逗点的数量
68+
void backtracking(string& s, int startIndex, int pointNum) {
69+
```
70+
71+
* 递归终止条件
72+
73+
终止条件和[回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)情况就不同了,本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。
74+
75+
pointNum表示逗点数量,pointNum为3说明字符串分成了4段了。
76+
77+
然后验证一下第四段是否合法,如果合法就加入到结果集里
5078

5179
代码如下:
5280

@@ -60,24 +88,40 @@ if (pointNum == 3) { // 逗点数量为3时,分隔结束
6088
}
6189
```
6290

63-
那么再来看循环遍历的过程如何截取子串。
91+
* 单层搜索的逻辑
92+
93+
[回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)中已经讲过在循环遍历中如何截取子串。
94+
95+
`for (int i = startIndex; i < s.size(); i++)`循环中 [startIndex, i]这个区间就是截取的子串,需要判断这个子串是否合法。
6496

65-
`for (int i = startIndex; i < s.size(); i++)`循环中 [startIndex, i]这个区间就是截取的子串,需要判断这个子串是否合法,如果合法就在字符串后面加上符号`.`表示已经分割。
97+
如果合法就在字符串后面加上符号`.`表示已经分割。
98+
99+
如果不合法就结束本层循环,如图中剪掉的分支:
100+
101+
<img src='../pics/93.复原IP地址.png' width=600> </img></div>
66102

67103
然后就是递归和回溯的过程:
68104

69-
递归调用时,下一层递归的startIndex要从i+2开始(因为刚刚在字符串中加入了分隔符`.`),同时记录分割符的数量pointNum 要 +1。
105+
递归调用时,下一层递归的startIndex要从i+2开始(因为需要在字符串中加入了分隔符`.`),同时记录分割符的数量pointNum 要 +1。
70106

71-
回溯的时候,就将刚刚加入的分隔符`.` 删掉就可以了,**pointNum其实也要减一,但是 pointNum+1 的逻辑放在递归函数的参数里了,这里相当于隐藏了回溯pointNum的过程**
107+
回溯的时候,就将刚刚加入的分隔符`.` 删掉就可以了,pointNum也要-1
72108

73-
递归和回溯代码如下
109+
代码如下
74110

75111
```
76-
// 插入逗点之后下一个子串的起始位置为i+2
77-
backtracking(s, i + 2, pointNum + 1);
78-
s.erase(s.begin() + i + 1); // 回溯时删掉逗点
112+
for (int i = startIndex; i < s.size(); i++) {
113+
if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法
114+
s.insert(s.begin() + i + 1 , '.'); // 在i的后面插入一个逗点
115+
pointNum++;
116+
backtracking(s, i + 2, pointNum); // 插入逗点之后下一个子串的起始位置为i+2
117+
pointNum--; // 回溯
118+
s.erase(s.begin() + i + 1); // 回溯删掉逗点
119+
} else break; // 不合法,直接结束本层循环
120+
}
79121
```
80122

123+
## 判断子串是否合法
124+
81125
最后就是在写一个判断段位是否是有效段位了。
82126

83127
主要考虑到如下三点:
@@ -111,9 +155,27 @@ bool isValid(const string& s, int start, int end) {
111155
}
112156
```
113157

114-
关键代码已经讲完,整体代码如下:
158+
## C++代码
159+
115160

116-
## C++代码
161+
根据[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)给出的回溯算法模板:
162+
163+
```
164+
void backtracking(参数) {
165+
if (终止条件) {
166+
存放结果;
167+
return;
168+
}
169+
170+
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
171+
处理节点;
172+
backtracking(路径,选择列表); // 递归
173+
回溯,撤销处理结果
174+
}
175+
}
176+
```
177+
178+
可以写出如下回溯算法C++代码:
117179

118180
```
119181
class Solution {
@@ -128,16 +190,14 @@ private:
128190
}
129191
return;
130192
}
131-
// 从起始位置开始构造字段字符串串
132193
for (int i = startIndex; i < s.size(); i++) {
133-
// 判断 [startIndex,i] 这个区间的子串是否合法
134-
if (isValid(s, startIndex, i)) {
135-
// 合法,在i的后面插入一个逗点
136-
s.insert(s.begin() + i + 1 , '.');
137-
// 插入逗点之后下一个子串的起始位置为i+2
138-
backtracking(s, i + 2, pointNum + 1);
139-
s.erase(s.begin() + i + 1); // 回溯时删掉逗点
140-
} else break;
194+
if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法
195+
s.insert(s.begin() + i + 1 , '.'); // 在i的后面插入一个逗点
196+
pointNum++;
197+
backtracking(s, i + 2, pointNum); // 插入逗点之后下一个子串的起始位置为i+2
198+
pointNum--; // 回溯
199+
s.erase(s.begin() + i + 1); // 回溯删掉逗点
200+
} else break; // 不合法,直接结束本层循环
141201
}
142202
}
143203
// 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法
@@ -167,6 +227,27 @@ public:
167227
return result;
168228
}
169229
};
230+
170231
```
171232

172-
> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
233+
# 总结
234+
235+
[回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)中我列举的分割字符串的难点,本题都覆盖了。
236+
237+
而且本题还需要操作字符串添加逗号作为分隔符,并验证区间的合法性。
238+
239+
可以说是[回溯算法:分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)的加强版。
240+
241+
在本文的树形结构图中,我已经把详细的分析思路都画了出来,相信大家看了之后一定会思路清晰不少!
242+
243+
**就酱,「代码随想录」值得推荐给你的朋友们!**
244+
245+
246+
一些录友表示跟不上现在的节奏,想从头开始打卡学习起来,可以在在公众号左下方,「算法汇总」可以找到历史文章,都是按系列排好顺序的,挨个看就可以了,别忘了打卡。
247+
248+
**很多录友都在从头开始打卡学习,看看前面文章的留言区就知道了,你并不孤单!**
249+
250+
251+
252+
> 我是[程序员Carl](https://github.com/youngyangyang04),更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),期待你的关注!
253+

problems/0127.单词接龙.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
2+
## 题目链接
3+
4+
https://leetcode-cn.com/problems/word-ladder/
5+
6+
## 思路
7+
8+
以示例1为例,从这个图中可以看出 hit 到 cog的路线,不止一条,有三条,两条是最短的长度为5,一条长度为6。
9+
10+
<img src='../pics/127.单词接龙.png' width=600> </img></div>
11+
12+
本题只需要求出最短长度就可以了,不用找出路径。
13+
14+
所以这道题要解决两个问题:
15+
16+
* 图中的线是如何连在一起的
17+
* 起点和终点的最短路径长度
18+
19+
20+
首先题目中并没有给出点与点之间的连线,而是要我们自己去连,条件是字符只能差一个,所以判断点与点之间的关系,要自己判断是不是差一个字符,如果差一个字符,那就是有链接。
21+
22+
然后就是求起点和终点的最短路径长度,**这里无向图求最短路,广搜最为合适,广搜只要搜到了终点,那么一定是最短的路径**。因为广搜就是以起点中心向四周扩散的搜索。
23+
24+
本题如果用深搜,会非常麻烦。
25+
26+
另外需要有一个注意点:
27+
28+
* 本题是一个无向图,需要用标记位,标记着节点是否走过,否则就会死循环!
29+
* 本题给出集合是数组型的,可以转成set结构,查找更快一些
30+
31+
C++代码如下:(详细注释)
32+
33+
```
34+
class Solution {
35+
public:
36+
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
37+
// 将vector转成unordered_set,提高查询速度
38+
unordered_set<string> wordSet(wordList.begin(), wordList.end());
39+
// 如果endWord没有在wordSet出现,直接返回0
40+
if (wordSet.find(endWord) == wordSet.end()) return 0;
41+
// 记录word是否访问过
42+
unordered_map<string, int> visitMap; // <word, 查询到这个word路径长度>
43+
// 初始化队列
44+
queue<string> que;
45+
que.push(beginWord);
46+
// 初始化visitMap
47+
visitMap.insert(pair<string, int>(beginWord, 1));
48+
49+
while(!que.empty()) {
50+
string word = que.front();
51+
que.pop();
52+
int path = visitMap[word]; // 这个word的路径长度
53+
for (int i = 0; i < word.size(); i++) {
54+
string newWord = word; // 用一个新单词替换word,因为每次置换一个字母
55+
for (int j = 0 ; j < 26; j++) {
56+
newWord[i] = j + 'a';
57+
if (newWord == endWord) return path + 1; // 找到了end,返回path+1
58+
// wordSet出现了newWord,并且newWord没有被访问过
59+
if (wordSet.find(newWord) != wordSet.end()
60+
&& visitMap.find(newWord) == visitMap.end()) {
61+
// 添加访问信息
62+
visitMap.insert(pair<string, int>(newWord, path + 1));
63+
que.push(newWord);
64+
}
65+
}
66+
}
67+
}
68+
return 0;
69+
}
70+
};
71+
```
72+
> 我是[程序员Carl](https://github.com/youngyangyang04),组队刷题可以找我,本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),期待你的关注!
73+

problems/0455.分发饼干.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
## 链接
3+
4+
https://leetcode-cn.com/problems/assign-cookies/
5+
6+
## 思路
7+
8+
这道题目呢,其实可以用较大大的饼干优先满足可以满足的胃口大的小孩。
9+
10+
注意我这里用的是 可以满足的胃口大的小孩。这样就不会造成大饼干的浪费。
11+
12+
所以使用贪心策略,讲饼干数组和小孩数组排序。
13+
14+
然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量的大小就可以了。
15+
16+
如图:
17+
18+
<img src='../pics/455.分发饼干.png' width=600> </img></div>
19+
20+
21+
C++代码整体如下:
22+
23+
```
24+
class Solution {
25+
public:
26+
int findContentChildren(vector<int>& g, vector<int>& s) {
27+
sort(g.begin(), g.end());
28+
sort(s.begin(), s.end());
29+
int index = s.size() - 1; // 饼干数组的下表
30+
int result = 0;
31+
for (int i = g.size() - 1; i >= 0; i--) {
32+
if (index >= 0 && s[index] >= g[i]) {
33+
result++;
34+
index--;
35+
}
36+
}
37+
return result;
38+
}
39+
};
40+
```
41+
> 我是[程序员Carl](https://github.com/youngyangyang04),组队刷题可以找我,本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),期待你的关注!
42+

0 commit comments

Comments
 (0)