Skip to content

Commit 7ff0587

Browse files
Update
1 parent 148060d commit 7ff0587

9 files changed

+188
-33
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
3+
## 题目地址
4+
5+
## 思路
6+
7+
8+
1. 数字和字母如何映射
9+
2. 两个字母我就两个for循环,三个字符我就三个for循环,以此类推,然后发现代码根本写不出来
10+
3. 如何排列组合呢
11+
4. 1 * # 等等情况
12+
13+
树形结构啊
14+
15+
## C++代码
16+
17+
```
18+
class Solution {
19+
private:
20+
const string letterMap[10] = {
21+
"", // 0
22+
"", // 1
23+
"abc", // 2
24+
"def", // 3
25+
"ghi", // 4
26+
"jkl", // 5
27+
"mno", // 6
28+
"pqrs", // 7
29+
"tuv", // 8
30+
"wxyz", // 9
31+
};
32+
public:
33+
vector<string> result;
34+
void getCombinations(const string& digits, int index, const string& s) {
35+
if (index == digits.size()) {
36+
result.push_back(s);
37+
return;
38+
}
39+
int digit = digits[index] - '0';
40+
string letters = letterMap[digit];
41+
for (int i = 0; i < letters.size(); i++) {
42+
getCombinations(digits, index + 1, s + letters[i]);
43+
}
44+
}
45+
vector<string> letterCombinations(string digits) {
46+
if (digits.size() == 0) {
47+
return result;
48+
}
49+
getCombinations(digits, 0, "");
50+
return result;
51+
52+
}
53+
};
54+
```
55+
56+
> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。

problems/0110.平衡二叉树.md

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,85 @@ https://leetcode-cn.com/problems/balanced-binary-tree/
33

44
## 思路
55

6+
递归三步曲分析:
7+
8+
1. 明确递归函数的参数和返回值
9+
10+
参数的话为传入的节点指针,就没有其他参数需要传递了,**返回值要注意,我们的返回值是要求传入节点为根节点树的深度**,否则如何标记左右子树是否差值大于1呢。
11+
12+
这里还要注意一点,如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,返回高度还有意义么? 此时可以返回-1 来标记已经不符合平衡树的规则了。
13+
14+
代码如下:
15+
16+
```
17+
int depth(TreeNode* node)
18+
```
19+
20+
2. 明确终止条件
21+
22+
递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的书高度为0
23+
24+
代码如下:
25+
26+
```
27+
if (node == NULL) {
28+
return 0;
29+
}
30+
```
31+
32+
3. 明确单层递归的逻辑
33+
34+
如何判断当前传入节点为根节点的二叉树是否是平衡二叉树呢,当然是左子树高度和右子树高度相差。
35+
36+
分别求出左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则则返回-1,表示已经不是二叉树了。
37+
38+
代码如下:
39+
40+
```
41+
int leftDepth = depth(node->left);
42+
if (leftDepth == -1) return -1;
43+
int rightDepth = depth(node->right);
44+
if (rightDepth == -1) return -1;
45+
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
46+
```
47+
48+
此时递归的函数就已经写出来了,这个递归的函数传入节点指针,返回以该节点为根节点的二叉树的高度,如果不是二叉平衡树了则返回-1。
49+
50+
代码如下:
51+
52+
```
53+
int depth(TreeNode* node) {
54+
if (node == NULL) {
55+
return 0;
56+
}
57+
int leftDepth = depth(node->left);
58+
if (leftDepth == -1) return -1;
59+
int rightDepth = depth(node->right);
60+
if (rightDepth == -1) return -1;
61+
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
62+
}
63+
```
64+
65+
整体代码如下:
666

767
## C++代码
868

969
```
1070
class Solution {
1171
public:
12-
// 一开始的想法是 遍历这棵树,然后针对每个节点判断其左右子树的深度
13-
14-
// 求node为头节点二叉树的深度,并且比较起左右节点的高度差
15-
// 平衡树的条件: 左子树是平衡树,右子树是平衡树,左右子树高度相差不超过1。
16-
// 递归三部曲
17-
// 1. 明确终止条件:如果node为null
18-
// 2. 明确返回信息: 判断左子树,判断右子树
19-
// 3. 一次递归要处理的逻辑
72+
// 返回以该节点为根节点的二叉树的高度,如果不是二叉搜索树了则返回-1
2073
int depth(TreeNode* node) {
2174
if (node == NULL) {
2275
return 0;
2376
}
24-
int left = depth(node->left);
25-
if (left == -1) return -1;
26-
int right = depth(node->right);
27-
if (right == -1) return -1;
28-
return abs(left - right) > 1 ? -1 : 1 + max(left, right);
77+
int leftDepth = depth(node->left);
78+
if (leftDepth == -1) return -1; // 说明左子树已经不是二叉平衡树
79+
int rightDepth = depth(node->right);
80+
if (rightDepth == -1) return -1; // 说明右子树已经不是二叉平衡树
81+
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
2982
}
3083
bool isBalanced(TreeNode* root) {
31-
return depth(root) == -1 ? false : true;
84+
return depth(root) == -1 ? false : true;
3285
}
3386
};
3487
```

problems/0225.用队列实现栈.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,30 @@ https://leetcode-cn.com/problems/implement-stack-using-queues/
44

55
## 思路
66

7-
有的同学可能疑惑这种题目有什么实际工程意义,其实很多算法题目主要是对知识点的考察和教学意义远大于其工程实践的意义,所以面试题也是这样!
7+
有的同学可能疑惑这种题目有什么实际工程意义,**其实很多算法题目主要是对知识点的考察和教学意义远大于其工程实践的意义,所以面试题也是这样!**
88

9-
用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质
9+
相信做过[0232.用栈实现队列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0232.用栈实现队列.md)这道题目的部分同学会依然想着用一个输入队列,一个输出队列,就可以模拟栈的功能,其实不是这样的。
1010

11-
建议大家题目编号: 225 和 232 一起做来做
11+
队列是先进先出的规则,你把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并有变成先进后出的顺序。
1212

13-
详细如代码注释所示
13+
所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。
14+
15+
如下面动画所示,**用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用**,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。
16+
17+
模拟的队列执行语句如下:
18+
queue.push(1);
19+
queue.push(2);
20+
queue.pop();
21+
queue.push(3);
22+
queue.push(4);
23+
queue.pop();
24+
queue.pop();
25+
queue.pop();
26+
queue.empty();
27+
28+
<video src='../video/225.用队列实现栈.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
29+
30+
详细如代码注释所示:
1431

1532
## C++代码
1633

problems/0232.用栈实现队列.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,28 @@ https://leetcode-cn.com/problems/implement-queue-using-stacks/
33

44
## 思路
55

6-
使用两个栈 一个输入栈,一个输出栈, 这里要注意输入栈和输出栈的关系,每当pop的时候且输出栈为空,就应该把输入站全部导入输出栈中
6+
使用**两个栈 一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。
7+
8+
下面动画模拟一下队列的执行过程如下:
9+
10+
执行语句:
11+
queue.push(1);
12+
queue.push(2);
13+
queue.pop(); **注意此时的输出栈的操作**
14+
queue.push(3);
15+
queue.push(4);
16+
queue.pop();
17+
queue.pop();**注意此时的输出栈的操作**
18+
queue.pop();
19+
queue.empty();
20+
21+
<video src='../video/232.用栈实现队列版本2.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
22+
23+
在push数据的时候,只要数据放进输入栈就好,**但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入)**,再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。
24+
25+
最后如何判断队列为空呢?**如果进栈和出栈都为空的话,说明模拟的队列为空了。**
26+
27+
代码如下:
728

829
## C++代码
930

problems/0242.有效的字母异位词.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,48 @@
22

33
https://leetcode-cn.com/problems/valid-anagram/
44

5-
## 思路
5+
> 数组就是简单的哈希表,但是数组的大小可不是无限开辟的
66
7-
先说一个特殊示例,输入:s = “car”, t= “car”,输出应该是什么呢? 后台判题逻辑返回的依然是true,其实这道题目真正题意是字符串s是否可以排练组合为字符串t。
7+
# 第242题.有效的字母异位词
88

9-
那么来看一下应该怎么做, 首先是暴力的解法,两层for循环,同时还要记录 字符是否重复出现,很明显时间复杂度是 O(n^2),暴力的方法这里就不做介绍了,直接看一下有没有更优的方式
9+
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词
1010

11-
数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。
11+
![](https://img-blog.csdnimg.cn/202008171902298.png)
12+
13+
**说明:**
14+
你可以假设字符串只包含小写字母。
15+
16+
# 思路
17+
18+
先看暴力的解法,两层for循环,同时还要记录字符是否重复出现,很明显时间复杂度是 O(n^2)。
19+
20+
暴力的方法这里就不做介绍了,直接看一下有没有更优的方式。
21+
22+
**数组其实就是一个简单哈希表**,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。
1223

1324
需要定义一个多大的数组呢,定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。
1425

1526
为了方便举例,判断一下字符串s= "aee", t = "eae"。
1627

1728
操作动画如下:
1829

19-
<img src='../video/242.有效的字母异位词.gif' width=600> </img></div>
30+
<img src='../video/242.有效的字母异位词.gif' width=600> </img></div>
2031

2132
定义一个数组叫做record用来上记录字符串s里字符出现的次数。
2233

23-
如何记录呢,需要把字符映射到数组也就是哈希表的索引下表上,那么**因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下表0,相应的字符z映射为下表25。**
34+
需要把字符映射到数组也就是哈希表的索引下表上,**因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下表0,相应的字符z映射为下表25。**
2435

2536
再遍历 字符串s的时候,**只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。** 这样就将字符串s中字符出现的次数,统计出来了。
2637

38+
那看一下如何检查字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
2739

28-
那看一下如何检查 字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
29-
30-
那么最后检查一下,**record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符,return false。**
40+
那么最后检查一下,**record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。**
3141

3242
最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
3343

3444
时间复杂度为O(n),空间上因为定义是的一个常量大小的辅助数组,所以空间复杂度为O(1)。
3545

36-
## C++ 代码
46+
# C++ 代码
3747
```
3848
class Solution {
3949
public:

problems/0617.合并二叉树.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,8 @@ public:
9090
while(!que.empty()) {
9191
TreeNode* node1 = que.front(); que.pop();
9292
TreeNode* node2 = que.front(); que.pop();
93-
// 两个节点不为空,val相加
94-
if (node1 != NULL && node2 != NULL) {
95-
node1->val += node2->val;
96-
}
93+
// 此时两个节点一定不为空,val相加
94+
node1->val += node2->val;
9795
// 如果左节点都不为空,加入队列
9896
if (node1->left != NULL && node2->left != NULL) {
9997
que.push(node1->left);

video/225.用队列实现栈.mp4

1.13 MB
Binary file not shown.

video/232.用栈实现队列.mp4

1.71 MB
Binary file not shown.
1.17 MB
Binary file not shown.

0 commit comments

Comments
 (0)