This commit is contained in:
youngyangyang04
2020-08-18 09:25:36 +08:00
parent ab7d15ea90
commit 6168d2c591
9 changed files with 188 additions and 33 deletions

View File

@ -0,0 +1,56 @@
## 题目地址
## 思路
1. 数字和字母如何映射
2. 两个字母我就两个for循环三个字符我就三个for循环以此类推然后发现代码根本写不出来
3. 如何排列组合呢
4. 1 * # 等等情况
树形结构啊
## C++代码
```
class Solution {
private:
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
public:
vector<string> result;
void getCombinations(const string& digits, int index, const string& s) {
if (index == digits.size()) {
result.push_back(s);
return;
}
int digit = digits[index] - '0';
string letters = letterMap[digit];
for (int i = 0; i < letters.size(); i++) {
getCombinations(digits, index + 1, s + letters[i]);
}
}
vector<string> letterCombinations(string digits) {
if (digits.size() == 0) {
return result;
}
getCombinations(digits, 0, "");
return result;
}
};
```
> 更多算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。

View File

@ -3,32 +3,85 @@ https://leetcode-cn.com/problems/balanced-binary-tree/
## 思路
递归三步曲分析:
1. 明确递归函数的参数和返回值
参数的话为传入的节点指针,就没有其他参数需要传递了,**返回值要注意,我们的返回值是要求传入节点为根节点树的深度**否则如何标记左右子树是否差值大于1呢。
这里还要注意一点,如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,返回高度还有意义么? 此时可以返回-1 来标记已经不符合平衡树的规则了。
代码如下:
```
int depth(TreeNode* node)
```
2. 明确终止条件
递归的过程中依然是遇到空节点了为终止返回0表示当前节点为根节点的书高度为0
代码如下:
```
if (node == NULL) {
return 0;
}
```
3. 明确单层递归的逻辑
如何判断当前传入节点为根节点的二叉树是否是平衡二叉树呢,当然是左子树高度和右子树高度相差。
分别求出左右子树的高度然后如果差值小于等于1则返回当前二叉树的高度否则则返回-1表示已经不是二叉树了。
代码如下:
```
int leftDepth = depth(node->left);
if (leftDepth == -1) return -1;
int rightDepth = depth(node->right);
if (rightDepth == -1) return -1;
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
```
此时递归的函数就已经写出来了,这个递归的函数传入节点指针,返回以该节点为根节点的二叉树的高度,如果不是二叉平衡树了则返回-1。
代码如下:
```
int depth(TreeNode* node) {
if (node == NULL) {
return 0;
}
int leftDepth = depth(node->left);
if (leftDepth == -1) return -1;
int rightDepth = depth(node->right);
if (rightDepth == -1) return -1;
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
}
```
整体代码如下:
## C++代码
```
class Solution {
public:
// 一开始的想法是 遍历这棵树,然后针对每个节点判断其左右子树的深度
// 求node为头节点二叉树的深度并且比较起左右节点的高度差
// 平衡树的条件: 左子树是平衡树右子树是平衡树左右子树高度相差不超过1。
// 递归三部曲
// 1. 明确终止条件如果node为null
// 2. 明确返回信息: 判断左子树,判断右子树
// 3. 一次递归要处理的逻辑
// 返回以该节点为根节点的二叉树的高度,如果不是二叉搜索树了则返回-1
int depth(TreeNode* node) {
if (node == NULL) {
return 0;
}
int left = depth(node->left);
if (left == -1) return -1;
int right = depth(node->right);
if (right == -1) return -1;
return abs(left - right) > 1 ? -1 : 1 + max(left, right);
int leftDepth = depth(node->left);
if (leftDepth == -1) return -1; // 说明左子树已经不是二叉平衡树
int rightDepth = depth(node->right);
if (rightDepth == -1) return -1; // 说明右子树已经不是二叉平衡树
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
}
bool isBalanced(TreeNode* root) {
return depth(root) == -1 ? false : true;
return depth(root) == -1 ? false : true;
}
};
```

View File

@ -4,13 +4,30 @@ https://leetcode-cn.com/problems/implement-stack-using-queues/
## 思路
有的同学可能疑惑这种题目有什么实际工程意义,其实很多算法题目主要是对知识点的考察和教学意义远大于其工程实践的意义,所以面试题也是这样!
有的同学可能疑惑这种题目有什么实际工程意义,**其实很多算法题目主要是对知识点的考察和教学意义远大于其工程实践的意义,所以面试题也是这样!**
用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质
相信做过[0232.用栈实现队列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0232.用栈实现队列.md)这道题目的部分同学会依然想着用一个输入队列,一个输出队列,就可以模拟栈的功能,其实不是这样的。
建议大家题目编号: 225 和 232 一起做来做
队列是先进先出的规则,你把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并有变成先进后出的顺序。
详细如代码注释所示
所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。
如下面动画所示,**用两个队列que1和que2实现队列的功能que2其实完全就是一个备份的作用**把que1最后面的元素以外的元素都备份到que2然后弹出最后面的元素再把其他元素从que2导回que1。
模拟的队列执行语句如下:
queue.push(1);
queue.push(2);
queue.pop();
queue.push(3);
queue.push(4);
queue.pop();
queue.pop();
queue.pop();
queue.empty();
<video src='../video/225.用队列实现栈.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
详细如代码注释所示:
## C++代码

View File

@ -3,7 +3,28 @@ https://leetcode-cn.com/problems/implement-queue-using-stacks/
## 思路
使用两个栈 一个输入栈,一个输出栈, 这里要注意输入栈和输出栈的关系每当pop的时候且输出栈为空就应该把输入站全部导入输出栈中
使用**两个栈 一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系
下面动画模拟一下队列的执行过程如下:
执行语句:
queue.push(1);
queue.push(2);
queue.pop(); **注意此时的输出栈的操作**
queue.push(3);
queue.push(4);
queue.pop();
queue.pop();**注意此时的输出栈的操作**
queue.pop();
queue.empty();
<video src='../video/232.用栈实现队列版本2.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
在push数据的时候只要数据放进输入栈就好**但在pop的时候操作就复杂一些输出栈如果为空就把进栈数据全部导入进来注意是全部导入**,再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。
最后如何判断队列为空呢?**如果进栈和出栈都为空的话,说明模拟的队列为空了。**
代码如下:
## C++代码

View File

@ -2,13 +2,24 @@
https://leetcode-cn.com/problems/valid-anagram/
## 思路
> 数组就是简单的哈希表,但是数组的大小可不是无限开辟的
先说一个特殊示例输入s = “car”, t= “car”输出应该是什么呢 后台判题逻辑返回的依然是true其实这道题目真正题意是字符串s是否可以排练组合为字符串t。
# 第242题.有效的字母异位词
那么来看一下应该怎么做, 首先是暴力的解法两层for循环同时还要记录 字符是否重复出现,很明显时间复杂度是 O(n^2),暴力的方法这里就不做介绍了,直接看一下有没有更优的方式
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词
数组其实就是一个简单哈希表而且这道题目中字符串只有小写字符那么就可以定义一个数组来记录字符串s里字符出现的次数。
![](https://img-blog.csdnimg.cn/202008171902298.png)
**说明:**
你可以假设字符串只包含小写字母。
# 思路
先看暴力的解法两层for循环同时还要记录字符是否重复出现很明显时间复杂度是 O(n^2)。
暴力的方法这里就不做介绍了,直接看一下有没有更优的方式。
**数组其实就是一个简单哈希表**而且这道题目中字符串只有小写字符那么就可以定义一个数组来记录字符串s里字符出现的次数。
需要定义一个多大的数组呢定一个数组叫做record大小为26 就可以了初始化为0因为字符a到字符z的ASCII也是26个连续的数值。
@ -16,24 +27,23 @@ https://leetcode-cn.com/problems/valid-anagram/
操作动画如下:
<img src='../video/242.有效的字母异位词.gif' width=600> </img></div>
<img src='../video/242.有效的字母异位词.gif' width=600> </img></div>
定义一个数组叫做record用来上记录字符串s里字符出现的次数。
如何记录呢,需要把字符映射到数组也就是哈希表的索引下表上,那么**因为字符a到字符z的ASCII是26个连续的数值所以字符a映射为下表0相应的字符z映射为下表25。**
需要把字符映射到数组也就是哈希表的索引下表上,**因为字符a到字符z的ASCII是26个连续的数值所以字符a映射为下表0相应的字符z映射为下表25。**
再遍历 字符串s的时候**只需要将 s[i] - a 所在的元素做+1 操作即可并不需要记住字符a的ASCII只要求出一个相对数值就可以了。** 这样就将字符串s中字符出现的次数统计出来了。
那看一下如何检查字符串t中是否出现了这些字符同样在遍历字符串t的时候对t中出现的字符映射哈希表索引上的数值再做-1的操作。
看一下如何检查 字符串t中是否出现了这些字符同样在遍历字符串t的时候对t中出现的字符映射哈希表索引上的数值再做-1的操作。
那么最后检查一下,**record数组如果有的元素不为零0说明字符串s和t 一定是谁多了字符或者谁少了字符return false。**
么最后检查一下,**record数组如果有的元素不为零0说明字符串s和t一定是谁多了字符或者谁少了字符return false。**
最后如果record数组所有元素都为零0说明字符串s和t是字母异位词return true。
时间复杂度为O(n)空间上因为定义是的一个常量大小的辅助数组所以空间复杂度为O(1)。
## C++ 代码
# C++ 代码
```
class Solution {
public:

View File

@ -90,10 +90,8 @@ public:
while(!que.empty()) {
TreeNode* node1 = que.front(); que.pop();
TreeNode* node2 = que.front(); que.pop();
// 两个节点不为空val相加
if (node1 != NULL && node2 != NULL) {
node1->val += node2->val;
}
// 此时两个节点一定不为空val相加
node1->val += node2->val;
// 如果左节点都不为空,加入队列
if (node1->left != NULL && node2->left != NULL) {
que.push(node1->left);

Binary file not shown.

Binary file not shown.

Binary file not shown.