diff --git a/README.md b/README.md
index 7e32a341..140304e8 100644
--- a/README.md
+++ b/README.md
@@ -14,8 +14,12 @@ LeetCode 最强题解(持续更新中):
|[0035.搜索插入位置](https://github.com/youngyangyang04/leetcode/blob/master/problems/0035.搜索插入位置.md) |数组 | **暴力** **二分**|
|[0053.最大子序和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0053.最大子序和.md) |数组 |**暴力** **贪心** 动态规划 分治|
|[0059.螺旋矩阵II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0059.螺旋矩阵II.md) |数组 |**模拟**|
+|[0083.删除排序链表中的重复元素](https://github.com/youngyangyang04/leetcode/blob/master/problems/0083.删除排序链表中的重复元素.md) |链表 |**模拟**|
+|[0203.移除链表元素](https://github.com/youngyangyang04/leetcode/blob/master/problems/0203.移除链表元素.md) |链表 |**模拟** **虚拟头结点**|
+|[0206.翻转链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0206.翻转链表.md) |链表 | **模拟** **递归**|
|[0209.长度最小的子数组](https://github.com/youngyangyang04/leetcode/blob/master/problems/0209.长度最小的子数组.md) |数组 | **暴力** **滑动窗口**|
-|[0237.删除链表中的节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/0237.删除链表中的节点.md) |链表 | **暴力**|
+|[0237.删除链表中的节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/0237.删除链表中的节点.md) |链表 | **原链表移除** **添加虚拟节点** 递归|
|[0383.赎金信](https://github.com/youngyangyang04/leetcode/blob/master/problems/0383.赎金信.md) |数组 |**暴力** **字典计数**|
+|[0707.设计链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0707.设计链表.md) |链表 |**模拟**|
diff --git a/pics/203_链表删除元素1.png b/pics/203_链表删除元素1.png
new file mode 100644
index 00000000..b32aa50e
Binary files /dev/null and b/pics/203_链表删除元素1.png differ
diff --git a/pics/203_链表删除元素2.png b/pics/203_链表删除元素2.png
new file mode 100644
index 00000000..5519a69d
Binary files /dev/null and b/pics/203_链表删除元素2.png differ
diff --git a/pics/203_链表删除元素3.png b/pics/203_链表删除元素3.png
new file mode 100644
index 00000000..cd50ce13
Binary files /dev/null and b/pics/203_链表删除元素3.png differ
diff --git a/pics/203_链表删除元素4.png b/pics/203_链表删除元素4.png
new file mode 100644
index 00000000..02aaf115
Binary files /dev/null and b/pics/203_链表删除元素4.png differ
diff --git a/pics/203_链表删除元素5.png b/pics/203_链表删除元素5.png
new file mode 100644
index 00000000..e24ad3d3
Binary files /dev/null and b/pics/203_链表删除元素5.png differ
diff --git a/pics/203_链表删除元素6.png b/pics/203_链表删除元素6.png
new file mode 100644
index 00000000..13f9b6d6
Binary files /dev/null and b/pics/203_链表删除元素6.png differ
diff --git a/pics/206_反转链表.png b/pics/206_反转链表.png
new file mode 100644
index 00000000..f26ad08f
Binary files /dev/null and b/pics/206_反转链表.png differ
diff --git a/problems/0035.搜索插入位置.md b/problems/0035.搜索插入位置.md
index 5b8f971b..5cea4c32 100644
--- a/problems/0035.搜索插入位置.md
+++ b/problems/0035.搜索插入位置.md
@@ -1,8 +1,8 @@
-## 题目地址
+# 题目地址
https://leetcode-cn.com/problems/search-insert-position/
-## 思路
+# 思路
这道题目其实是一道很简单的题,但是为什么通过率相对来说并不高呢,我理解是大家对 边界处理的判断有所失误,导致的。
@@ -22,7 +22,7 @@ https://leetcode-cn.com/problems/search-insert-position/
这里我给出了一种简洁的暴力解法,和两种二分查找的解法
-## 解法:暴力枚举
+# 解法:暴力枚举
```
class Solution {
@@ -49,7 +49,7 @@ public:
时间复杂度:O(1)
-## 二分法
+# 二分法
既然暴力解法的时间复杂度是On,我们就要尝试一下使用二分查找法。
@@ -73,7 +73,7 @@ public:
我们要在二分查找的过程中,保持不变量,这也就是**循环不变量** (感兴趣的同学可以查一查)
-### 二分法第一种写法
+## 二分法第一种写法
以这道题目来举例,以下的代码中我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right]
@@ -111,7 +111,7 @@ public:
效率如下:
-### 二分法第二种写法
+## 二分法第二种写法
如果说我们定义 target 是在一个在左闭右开的区间里,也就是[left, right)
diff --git a/problems/0083.删除排序链表中的重复元素.md b/problems/0083.删除排序链表中的重复元素.md
new file mode 100644
index 00000000..39c50b94
--- /dev/null
+++ b/problems/0083.删除排序链表中的重复元素.md
@@ -0,0 +1,38 @@
+
+## 题目地址
+
+https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/
+
+## 思路
+
+这道题目没有必要设置虚拟节点,因为不会删除头结点
+
+## 代码
+
+```
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * ListNode *next;
+ * ListNode(int x) : val(x), next(NULL) {}
+ * };
+ */
+class Solution {
+public:
+ ListNode* deleteDuplicates(ListNode* head) {
+ ListNode* p = head;
+ while (p != NULL && p->next!= NULL) {
+ if (p->val == p->next->val) {
+ ListNode* tmp = p->next;
+ p->next = p->next->next;
+ delete tmp;
+ } else {
+ p = p->next;
+ }
+ }
+ return head;
+ }
+};
+```
+
diff --git a/problems/0142.环形链表II.md b/problems/0142.环形链表II.md
new file mode 100644
index 00000000..69c41eec
--- /dev/null
+++ b/problems/0142.环形链表II.md
@@ -0,0 +1,46 @@
+## 题目地址
+https://leetcode-cn.com/problems/linked-list-cycle-ii/
+
+## 思路
+
+快慢指针为什么一定会相遇
+
+
+
+1.第一次相遇,slow = nb
+2.a+nb = 入口点
+3.slow再走a = 入口 = head走到入口 = a
+4.由3得出,起始距离入口 = 第一次相遇位置 + a
+
+## 代码
+
+```
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * ListNode *next;
+ * ListNode(int x) : val(x), next(NULL) {}
+ * };
+ */
+class Solution {
+public:
+ ListNode *detectCycle(ListNode *head) {
+ ListNode* fast = head;
+ ListNode* slow = head;
+ while(fast != NULL && fast->next != NULL) {
+ slow = slow->next;
+ fast = fast->next->next;
+ if (slow == fast) { // 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
+ slow = head;
+ while (slow != fast) {
+ fast = fast->next;
+ slow = slow->next;
+ }
+ return fast; // 返回环的入口
+ }
+ }
+ return NULL;
+ }
+};
+```
diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md
new file mode 100644
index 00000000..3aef4d2e
--- /dev/null
+++ b/problems/0203.移除链表元素.md
@@ -0,0 +1,130 @@
+## 题目地址
+
+https://leetcode-cn.com/problems/remove-linked-list-elements/
+
+## 思路
+
+我们这里以链表 1 4 2 4 来举例,移除元素4
+
+
+
+如果使用C,C++编程语言的话,不要忘了还要从内存中删除这两个移除的节点, 清理节点内存之后如图:
+
+
+
+**当然如果使用java ,python的话就不用手动管理内存了。**
+
+还要说明一下,就算我们使用C++来做leetcode,如果移除一个节点之后,没有手动在内存中删除这个节点,leetcode依然也是可以通过的,只不过,内存使用的空间大一些而已,但建议同学们依然要养生手动清理内存的习惯,因为在面试中 这些细节都是面试官考察的点
+
+这种情况下的移除操作,就是让节点next指针直接指向下下一个节点就可以了,
+
+那么因为单链表的特殊性,只能指向下一个节点,我们刚刚删除的是 链表的中第二个,和第四个节点,那么如果我们删除的是头结点 又该怎么办呢
+
+这里就涉及到 链表操作的两种方式,**一种是 直接使用原来的链表来进行删除操作,一种是设置一个虚拟头结点在进行删除操作。**
+
+
+
+我们来看第一种操作 直接使用原来的链表来进行移除
+
+
+
+移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点
+
+所以头结点如何移除呢,其实我们只要 将头结点向后移动一位就可以,这样我们就从链表中移除了一个头结点
+
+
+
+
+依然别忘将原头结点从内存中删掉
+
+
+
+这样我们移除了一个头结点,是不是发现,在单链表中移除头结点 和 移除其他节点的操作方式是不一样,其实在我们写代码的时候也会发现,需要单独写一段逻辑来处理 移除头结点的情况。
+
+那么可不可以 以一种统一的逻辑来移除 链表的节点呢。
+
+其实我们可以设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了。
+
+我们来看看如何设置一个虚拟头。我们依然还是在这个链表中,移除元素1。
+
+
+
+
+这里我们来给链表添加一个虚拟头结点为新的头结点,此时我们要移除这个旧头结点 元素1,
+
+这样是不是就可以使用 和移除链表其他节点的方式统一了呢
+
+大家来看一下,如何移除元素1 呢,还是我们熟悉的方式,然后从内存中删除元素1
+
+最后呢在题目中,return 头结点的时候,别让了 `return dummyNode->next;`, 这才是新的头结点
+
+
+## 代码
+
+```
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * ListNode *next;
+ * ListNode(int x) : val(x), next(NULL) {}
+ * };
+ */
+// 直接使用原来的链表来进行移除节点操作
+class Solution {
+public:
+ ListNode* removeElements(ListNode* head, int val) {
+ // 删除头结点
+ while (head != NULL && head->val == val) { // 注意这里不是if
+ ListNode* tmp = head;
+ head = head->next;
+ delete tmp;
+ }
+
+ // 删除非头结点
+ ListNode* cur = head;
+ while (cur != NULL && cur->next!= NULL) {
+ if (cur->next->val == val) {
+ ListNode* tmp = cur->next;
+ cur->next = cur->next->next;
+ delete tmp;
+ } else {
+ cur = cur->next;
+ }
+ }
+ return head;
+ }
+};
+```
+
+
+```
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * ListNode *next;
+ * ListNode(int x) : val(x), next(NULL) {}
+ * };
+ */
+// 设置一个虚拟头结点在进行移除节点操作
+class Solution {
+public:
+ ListNode* removeElements(ListNode* head, int val) {
+ ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
+ dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
+ ListNode* cur = dummyHead;
+
+ while (cur->next != NULL) {
+ if(cur->next->val == val) {
+ ListNode* tmp = cur->next;
+ cur->next = cur->next->next;
+ delete tmp;
+ } else {
+ cur = cur->next;
+ }
+ }
+ return dummyHead->next;
+ }
+};
+```
diff --git a/problems/0206.翻转链表.md b/problems/0206.翻转链表.md
new file mode 100644
index 00000000..5746ae3b
--- /dev/null
+++ b/problems/0206.翻转链表.md
@@ -0,0 +1,56 @@
+## 题目地址
+
+https://leetcode-cn.com/problems/reverse-linked-list/
+
+## 思路
+
+其实只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表,如图所示
+
+
+
+## 代码
+
+### 模拟算法
+```
+/**
+ * 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) {
+ ListNode* temp; // 保存cur的下一个节点
+ ListNode* cur = head;
+ ListNode* pre = NULL;
+ while(cur) {
+ temp = cur->next; // 保存一下 cur的下一个节点,因为接下来要改变cur->next
+ cur->next = pre; // 翻转操作
+ // 更新pre 和 cur指针
+ pre = cur;
+ cur = temp;
+ }
+ return pre;
+ }
+};
+```
+
+### 递归算法
+```
+class Solution {
+public:
+ ListNode* reverse(ListNode* pre,ListNode* cur){
+ if(cur == NULL) return pre;
+ ListNode* temp = cur->next;
+ cur->next = pre;
+ return reverse(cur,temp);
+ }
+ ListNode* reverseList(ListNode* head) {
+ return reverse(NULL, head);
+ }
+
+};
+```
diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md
new file mode 100644
index 00000000..4e23bb18
--- /dev/null
+++ b/problems/0707.设计链表.md
@@ -0,0 +1,110 @@
+## 题目地址
+
+https://leetcode-cn.com/problems/design-linked-list/
+
+## 思路
+
+这道题目设计链表的五个接口
+* 获取链表第index个节点的数值
+* 在链表的最前面插入一个节点
+* 在链表的最后面插入一个节点
+* 在链表第index个节点前面插入一个节点
+* 删除链表的第index个节点
+
+可以说这五个接口,已经覆盖了链表的常见操作,是练习链表操作非常好的一道题目
+
+## 代码
+```
+class MyLinkedList {
+public:
+ // 定义链表节点结构体
+ struct LinkedNode {
+ int val;
+ LinkedNode* next;
+ LinkedNode(int val):val(val), next(nullptr){}
+ };
+
+ // 初始化链表
+ MyLinkedList() {
+ _dummyHead = new LinkedNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
+ _size = 0;
+ }
+
+ // 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
+ int get(int index) {
+ if (index > (_size - 1) || index < 0) {
+ return -1;
+ }
+ LinkedNode* cur = _dummyHead->next;
+ while(index--){ // 如果--index 就会陷入死循环
+ cur = cur->next;
+ }
+ return cur->val;
+ }
+
+ // 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点
+ void addAtHead(int val) {
+ LinkedNode* newNode = new LinkedNode(val);
+ newNode->next = _dummyHead->next;
+ _dummyHead->next = newNode;
+ _size++;
+ }
+
+ // 在链表最后面添加一个节点
+ void addAtTail(int val) {
+ LinkedNode* newNode = new LinkedNode(val);
+ LinkedNode* cur = _dummyHead;
+ while(cur->next != nullptr){
+ cur = cur->next;
+ }
+ cur->next = newNode;
+ _size++;
+ }
+
+ // 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
+ // 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
+ // 如果index大于链表的长度,则返回空
+ void addAtIndex(int index, int val) {
+ if (index > _size) {
+ return;
+ }
+ LinkedNode* newNode = new LinkedNode(val);
+ LinkedNode* cur = _dummyHead;
+ while(index--) {
+ cur = cur->next;
+ }
+ newNode->next = cur->next;
+ cur->next = newNode;
+ _size++;
+ }
+
+ // 删除第index个节点,如果index 大于等于链表的长度,直接return,注意index是从0开始的
+ void deleteAtIndex(int index) {
+ if (index >= _size || index < 0) {
+ return;
+ }
+ LinkedNode* cur = _dummyHead;
+ while(index--) {
+ cur = cur ->next;
+ }
+ LinkedNode* tmp = cur->next;
+ cur->next = cur->next->next;
+ delete tmp;
+ _size--;
+ }
+
+ // 打印链表
+ void printLinkedList() {
+ LinkedNode* cur = _dummyHead;
+ while (cur->next != nullptr) {
+ cout << cur->next->val << " ";
+ cur = cur->next;
+ }
+ cout << endl;
+ }
+private:
+ int _size;
+ LinkedNode* _dummyHead;
+
+};
+```