This commit is contained in:
youngyangyang04
2020-08-15 18:25:23 +08:00
parent ef76ad8cda
commit 84fe2e4e3b
9 changed files with 101 additions and 29 deletions

View File

@ -362,7 +362,7 @@ int countNodes(TreeNode* root) {
|[0202.快乐数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0202.快乐数.md) |哈希表 |简单|**哈希**|
|[0203.移除链表元素](https://github.com/youngyangyang04/leetcode/blob/master/problems/0203.移除链表元素.md) |链表 |简单|**模拟** **虚拟头结点**|
|[0205.同构字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0205.同构字符串.md) |哈希表 |简单| **哈希**|
|[0206.翻转链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0206.翻转链表.md) |链表 |简单| **模拟** **递归**|
|[0206.翻转链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0206.翻转链表.md) |链表 |简单| **双指针法** **递归**|
|[0209.长度最小的子数组](https://github.com/youngyangyang04/leetcode/blob/master/problems/0209.长度最小的子数组.md) |数组 |中等| **暴力** **滑动窗口**|
|[0219.存在重复元素II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0219.存在重复元素II.md) | 哈希表 |简单| **哈希** |
|[0222.完全二叉树的节点个数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0222.完全二叉树的节点个数.md) | 树 |简单| **递归** |

View File

@ -4,22 +4,34 @@ https://leetcode-cn.com/problems/reverse-linked-list/
## 思路
其实只需要改变链表的next指针的指向直接将链表反转 ,而不用重新定义一个新的链表,如图所示
如果再定义一个新的链表,实现链表元素的反转,其实这是对内存空间的浪费。
其实只需要改变链表的next指针的指向直接将链表反转 ,而不用重新定义一个新的链表,如图所示:
<img src='../pics/206_反转链表.png' width=600> </img></div>
## 代码
之前链表的头节点是元素1 反转之后头结点就是元素5 这里并没有添加或者删除节点仅仅是改表next指针的方向。
那么接下来看一看是如何反转呢?
我们拿有示例中的链表来举例,如动画所示:
<video src='../video/206.翻转链表.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
首先定义一个cur指针指向头结点再定义一个pre指针初始化为null。
然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下也就是保存一下这个节点。
为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了将cur->next 指向pre ,此时已经反转了第一个节点了。
接下来就是循环走如下代码逻辑了继续移动pre和cur指针。
最后cur 指针已经指向了null循环结束链表也反转完毕了。 此时我们return pre指针就可以了pre指针就指向了新的头结点。
## C++代码
### 模拟算法
```
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {

View File

@ -15,12 +15,38 @@ https://leetcode-cn.com/problems/reverse-string/
接下来我们再来讲一下如何解决反转字符串的问题。
这道题目遍历数组的前一半,同时和后一半做交换就可以了。
这道题目遍历数组的前一半,同时和后一半做交换就可以了
<img src='../video/344.反转字符串.gif' width=600> </img></div>
此时我们再看一下代码实现
C++代码如下:
```
void reverseString(vector<char>& s) {
for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) {
swap(s[i],s[j]);
}
}
```
## 代码
循环里只要做交换s[i] 和s[j]操作就可以了那么我这里使用了swap 这个库函数,因为知道交换函数如何实现, 而且库函数仅仅是解题中的一部分, 所以这里使用库函数也是可以的。 swap可以有两种实现。
一种就是常见的交换数值。
```
int tmp = s[i];
s[i] = s[j];
s[j] = tmp;
```
一种就是通过位运算。
```
s[i] ^= s[j];
s[j] ^= s[i];
s[i] ^= s[j];
```
## C++代码
```
class Solution {

View File

@ -3,15 +3,30 @@ https://leetcode-cn.com/problems/delete-node-in-a-bst/
## 思路
平衡二叉树中删除节点有三种情况
平衡二叉树中删除节点一下五种情况
* 没找到删除的节点,遍历到空节点直接返回了
* 第一种情况:没找到删除的节点,遍历到空节点直接返回了
* 找到删除的节点
* 左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
* 其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
* 其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
* 左右孩子节点都不为空,则将删除节点的左孩子放到删除节点的右孩子的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
* 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
* 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
* 第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
* 第五种情况:左右孩子节点都不为空,则将删除节点的左孩子放到删除节点的右孩子的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
第五种情况有点难以理解,看下面动画:
动画中颗二叉搜索树中删除元素7 那么删除节点元素7的左孩子就是5删除节点元素7的右孩子的最左面节点是元素8。
将将删除节点元素7的左孩子放到删除节点元素7的右孩子的最左面节点的左孩子上就是把5为根节点的子树移到了8的左孩子的位置。
接着删除节点元素7右孩子为新的根节点。click也就是元素7位根节点的树现在的根节点变成元素9的根节点的树了.
<video src='../video/450.删除二叉搜索树中的节点.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
这样就完成删除元素7的逻辑也可以动手画一个图尝试删除一个节点试试。
代码如下:(详细注释)
## C++代码
@ -19,14 +34,14 @@ https://leetcode-cn.com/problems/delete-node-in-a-bst/
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (root == NULL) return root;
if (root == NULL) return root; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了
if (root->val == key) {
// 第种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
// 第种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
// 第种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
// 第种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
if (root->left == NULL) return root->right;
// 第种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
// 第种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
else if (root->right == NULL) return root->left;
// 第种情况:左右孩子节点都不为空,则将删除节点的左孩子放到删除节点的右孩子的最左面节点的左孩子的位置
// 第种情况:左右孩子节点都不为空,则将删除节点的左孩子放到删除节点的右孩子的最左面节点的左孩子的位置
// 返回删除节点右孩子为新的根节点。
else {
TreeNode* cur = root->right;

View File

@ -1,10 +1,29 @@
## 题目地址
# 题目地址
https://leetcode-cn.com/problems/design-linked-list/
## 思路
> 听说这道题目把链表常见的五个操作都覆盖了?
如果链表的基础知识还不太懂,可以看这篇文章:[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ)
# 第707题设计链表
题意:
在链表类中实现这些功能:
* get(index)获取链表中第 index 个节点的值。如果索引无效则返回-1。
* addAtHead(val)在链表的第一个元素之前添加一个值为 val 的节点。插入后新节点将成为链表的第一个节点。
* addAtTail(val)将值为 val 的节点追加到链表的最后一个元素。
* addAtIndex(index,val)在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度则该节点将附加到链表的末尾。如果 index 大于链表长度则不会插入节点。如果index小于0则在头部插入节点。
* deleteAtIndex(index)如果索引 index 有效则删除链表中的第 index 个节点。
![707示例](https://img-blog.csdnimg.cn/20200814200558953.png)
# 思路
如果对链表的基础知识还不太懂,可以看这篇文章:[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ)
如果对链表的虚拟头结点不清楚,可以看这篇文章:[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA)
删除链表节点:
![链表-删除节点](https://img-blog.csdnimg.cn/20200806195114541.png)
@ -26,7 +45,7 @@ https://leetcode-cn.com/problems/design-linked-list/
1. 直接使用原来的链表来进行操作。
2. 设置一个虚拟头结点在进行操作。
下面采用的设置一个虚拟头结点(这样更方便一些,大家看代码就会感受出来)。
下面采用的设置一个虚拟头结点(这样更方便一些,大家看代码就会感受出来)。
## 代码

BIN
video/206.翻转链表.mp4 Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

Binary file not shown.