diff --git a/README.md b/README.md index c5e1e504..22b2103a 100644 --- a/README.md +++ b/README.md @@ -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) | 树 |简单| **递归** | diff --git a/problems/0206.翻转链表.md b/problems/0206.翻转链表.md index 5b900ba6..1bd3bc41 100644 --- a/problems/0206.翻转链表.md +++ b/problems/0206.翻转链表.md @@ -4,22 +4,34 @@ https://leetcode-cn.com/problems/reverse-linked-list/ ## 思路 -其实只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表,如图所示 +如果再定义一个新的链表,实现链表元素的反转,其实这是对内存空间的浪费。 + +其实只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表,如图所示: -## 代码 +之前链表的头节点是元素1, 反转之后头结点就是元素5 ,这里并没有添加或者删除节点,仅仅是改表next指针的方向。 + +那么接下来看一看是如何反转呢? + +我们拿有示例中的链表来举例,如动画所示: + + + +首先定义一个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) { diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md index afb6e3d3..dc4c907b 100644 --- a/problems/0344.反转字符串.md +++ b/problems/0344.反转字符串.md @@ -15,12 +15,38 @@ https://leetcode-cn.com/problems/reverse-string/ 接下来我们再来讲一下如何解决反转字符串的问题。 +这道题目遍历数组的前一半,同时和后一半做交换就可以了。 -这道题目遍历数组的前一半,同时和后一半做交换就可以了 + -此时我们再看一下代码实现 +C++代码如下: +``` +void reverseString(vector& 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 { diff --git a/problems/0450.删除二叉搜索树中的节点.md b/problems/0450.删除二叉搜索树中的节点.md index 4aa4679e..7f024675 100644 --- a/problems/0450.删除二叉搜索树中的节点.md +++ b/problems/0450.删除二叉搜索树中的节点.md @@ -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的根节点的树了. + + + + + +这样就完成删除元素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; diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index 82fd3f1b..01bd71f3 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -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. 设置一个虚拟头结点在进行操作。 -下面我采用的设置一个虚拟头结点(这样更方便一些,大家看代码就会感受出来)。 +下面采用的设置一个虚拟头结点(这样更方便一些,大家看代码就会感受出来)。 ## 代码 diff --git a/video/206.翻转链表.mp4 b/video/206.翻转链表.mp4 new file mode 100644 index 00000000..02d66ccb Binary files /dev/null and b/video/206.翻转链表.mp4 differ diff --git a/video/344.反转字符串.gif b/video/344.反转字符串.gif new file mode 100644 index 00000000..b99ef086 Binary files /dev/null and b/video/344.反转字符串.gif differ diff --git a/video/344.反转字符串.mp4 b/video/344.反转字符串.mp4 new file mode 100644 index 00000000..80877057 Binary files /dev/null and b/video/344.反转字符串.mp4 differ diff --git a/video/450.删除二叉搜索树中的节点.mp4 b/video/450.删除二叉搜索树中的节点.mp4 new file mode 100644 index 00000000..a835887d Binary files /dev/null and b/video/450.删除二叉搜索树中的节点.mp4 differ