验证,校对

This commit is contained in:
jaredliw 2021-07-16 00:06:52 +08:00
parent 4a8c81e88e
commit 88fcd88712
14 changed files with 180 additions and 197 deletions

View File

@ -1,5 +1,3 @@
> 如果阅读时发现错误或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** 备注 github + 题目 + 问题 向我反馈 > 如果阅读时发现错误或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** 备注 github + 题目 + 问题 向我反馈
> >
> 感谢支持该仓库会一直维护希望对各位有一丢丢帮助 > 感谢支持该仓库会一直维护希望对各位有一丢丢帮助
@ -63,7 +61,6 @@ class Solution {
return true; return true;
} }
} }
``` ```
C++ Code: C++ Code:
@ -72,18 +69,23 @@ C++ Code:
class Solution { class Solution {
public: public:
bool isPalindrome(ListNode* head) { bool isPalindrome(ListNode* head) {
//这里需要用动态数组因为我们不知道链表的长度
vector<int> arr; vector<int> arr;
ListNode* copynode = head; ListNode* copynode = head;
//将链表的值复制到数组中
while (copynode) { while (copynode) {
arr.push_back(copynode->val); arr.push_back(copynode->val);
copynode = copynode->next; copynode = copynode->next;
} }
//双指针遍历数组
int back = 0; int back = 0;
int pro = arr.size() - 1; int pro = arr.size() - 1;
while (back < pro) { while (back < pro) {
//判断两个指针的值是否相等
if (arr[back] != arr[pro]) { if (arr[back] != arr[pro]) {
return false; return false;
} }
//移动指针
back++; back++;
pro--; pro--;
} }
@ -121,7 +123,7 @@ var isPalindrome = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def isPalindrome(self, head: ListNode) -> bool: def isPalindrome(self, head: ListNode) -> bool:
arr = [] arr = []
@ -145,7 +147,7 @@ class Solution:
这个方法可以直接通过但是这个方法需要辅助数组那我们还有其他更好的方法吗 这个方法可以直接通过但是这个方法需要辅助数组那我们还有其他更好的方法吗
双指针翻转链表法 **双指针翻转链表法**
在上个题目中我们知道了如何找到链表的中间节点那我们可以在找到中间节点之后对后半部分进行翻转翻转之后重新遍历前半部分和后半部分进行判断是否为回文 在上个题目中我们知道了如何找到链表的中间节点那我们可以在找到中间节点之后对后半部分进行翻转翻转之后重新遍历前半部分和后半部分进行判断是否为回文
@ -165,17 +167,17 @@ class Solution {
} }
//找到中间节点也就是翻转的头节点,这个在昨天的题目中讲到 //找到中间节点也就是翻转的头节点,这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是如果有两个中间节点返回第一个昨天的题目是第二个 //但是今天和昨天有一些不一样的地方就是如果有两个中间节点返回第一个昨天的题目是第二个
ListNode midenode = searchmidnode(head); ListNode midnode = searchmidnode(head);
//原地翻转链表需要两个辅助指针这个也是面试题目大家可以做一下 //原地翻转链表需要两个辅助指针这个也是面试题目大家可以做一下
//这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分 //这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分
ListNode backhalf = reverse(midenode.next); ListNode backhalf = reverse(midnode.next);
//遍历两部分链表判断值是否相等 //遍历两部分链表判断值是否相等
ListNode p1 = head; ListNode p1 = head;
ListNode p2 = backhalf; ListNode p2 = backhalf;
while (p2 != null) { while (p2 != null) {
if (p1.val != p2.val) { if (p1.val != p2.val) {
//若要还原记得这里也要reverse //若要还原记得这里也要reverse
midenode.next = reverse(backhalf); midnode.next = reverse(backhalf);
return false; return false;
} }
p1 = p1.next; p1 = p1.next;
@ -183,7 +185,7 @@ class Solution {
} }
//还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文 //还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条 //当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条
midenode.next = reverse(backhalf); midnode.next = reverse(backhalf);
return true; return true;
} }
//找到中点 //找到中点
@ -222,17 +224,17 @@ public:
} }
//找到中间节点也就是翻转的头节点这个在昨天的题目中讲到 //找到中间节点也就是翻转的头节点这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是如果有两个中间节点返回第一个昨天的题目是第二个 //但是今天和昨天有一些不一样的地方就是如果有两个中间节点返回第一个昨天的题目是第二个
ListNode * midenode = searchmidnode(head); ListNode * midnode = searchmidnode(head);
//原地翻转链表需要两个辅助指针这个也是面试题目大家可以做一下 //原地翻转链表需要两个辅助指针这个也是面试题目大家可以做一下
//这里我们用的是midnode->next需要注意因为我们找到的是中点但是我们翻转的是后半部分 //这里我们用的是midnode->next需要注意因为我们找到的是中点但是我们翻转的是后半部分
ListNode * backhalf = reverse(midenode->next); ListNode * backhalf = reverse(midnode->next);
//遍历两部分链表判断值是否相等 //遍历两部分链表判断值是否相等
ListNode * p1 = head; ListNode * p1 = head;
ListNode * p2 = backhalf; ListNode * p2 = backhalf;
while (p2 != nullptr) { while (p2 != nullptr) {
if (p1->val != p2->val) { if (p1->val != p2->val) {
//若要还原记得这里也要reverse //若要还原记得这里也要reverse
midenode.next = reverse(backhalf); midnode->next = reverse(backhalf);
return false; return false;
} }
p1 = p1->next; p1 = p1->next;
@ -240,7 +242,7 @@ public:
} }
//还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文 //还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条 //当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条
midenode->next = reverse(backhalf); midnode->next = reverse(backhalf);
return true; return true;
} }
//找到中间的部分 //找到中间的部分
@ -277,17 +279,17 @@ var isPalindrome = function(head) {
} }
//找到中间节点也就是翻转的头节点这个在昨天的题目中讲到 //找到中间节点也就是翻转的头节点这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是如果有两个中间节点返回第一个昨天的题目是第二个 //但是今天和昨天有一些不一样的地方就是如果有两个中间节点返回第一个昨天的题目是第二个
let midenode = searchmidnode(head); let midnode = searchmidnode(head);
//原地翻转链表需要两个辅助指针这个也是面试题目大家可以做一下 //原地翻转链表需要两个辅助指针这个也是面试题目大家可以做一下
//这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分 //这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分
let backhalf = reverse(midenode.next); let backhalf = reverse(midnode.next);
//遍历两部分链表判断值是否相等 //遍历两部分链表判断值是否相等
let p1 = head; let p1 = head;
let p2 = backhalf; let p2 = backhalf;
while (p2 != null) { while (p2 != null) {
if (p1.val != p2.val) { if (p1.val != p2.val) {
//若要还原记得这里也要reverse //若要还原记得这里也要reverse
midenode.next = reverse(backhalf); midnode.next = reverse(backhalf);
return false; return false;
} }
p1 = p1.next; p1 = p1.next;
@ -295,7 +297,7 @@ var isPalindrome = function(head) {
} }
//还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文 //还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条 //当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条
midenode.next = reverse(backhalf); midnode.next = reverse(backhalf);
return true; return true;
}; };
@ -326,7 +328,7 @@ var reverse = function(slow) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def isPalindrome(self, head: ListNode) -> bool: def isPalindrome(self, head: ListNode) -> bool:
if head is None or head.next is None: if head is None or head.next is None:
@ -344,12 +346,11 @@ class Solution:
if p1.val != p2.val: if p1.val != p2.val:
# 若要还原记得这里也要reverse # 若要还原记得这里也要reverse
midnode.next = self.reverse(backhalf) midnode.next = self.reverse(backhalf)
print(head)
return False return False
p1 = p1.next p1 = p1.next
p2 = p2.next p2 = p2.next
# 还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文 # 还原链表并返回结果这一步是需要注意的我们不可以破坏初始结构我们只是判断是否为回文
当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条 # 当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条
midnode.next = self.reverse(backhalf) midnode.next = self.reverse(backhalf)
return True return True

View File

@ -56,22 +56,6 @@ public class Solution {
} }
``` ```
JS Code:
```javascript
var hasCycle = function(head) {
let fast = head;
let slow = head;
while (fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
if (fast === slow) {
return true;
}
}
return false;
};
```
C++ Code: C++ Code:
```cpp ```cpp
@ -92,17 +76,34 @@ public:
}; };
``` ```
JS Code:
```javascript
var hasCycle = function(head) {
let fast = head;
let slow = head;
while (fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
if (fast === slow) {
return true;
}
}
return false;
};
```
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def hasCycle(self, head: ListNode) -> bool: def hasCycle(self, head: ListNode) -> bool:
fast = head fast = head
slow = head slow = head
while fast and fast.next: while fast and fast.next:
fast = fast.next.next fast = fast.next.next
low = low.next slow = slow.next
if fast == low: if fast == slow:
return True return True
return False return False
``` ```

View File

@ -18,35 +18,7 @@
我们可以这样假设两个孩子在操场顺时针跑步一个跑的快一个跑的慢跑的快的那个孩子总会追上跑的慢的孩子 我们可以这样假设两个孩子在操场顺时针跑步一个跑的快一个跑的慢跑的快的那个孩子总会追上跑的慢的孩子
环形链表 代码请参考[动画模拟leetcode 141 环形链表](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode141%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8.md)
```java
public class Solution {
public boolean hasCycle(ListNode head) {
//特殊情况无节点或只有一个节点的情况
if(head == null || head.next == null){
return false;
}
//设置快慢指针
ListNode pro = head.next;
ListNode last = head;
//循环条件
while( pro != null && pro.next!=null){
pro=pro.next.next;
last=last.next;
//两指针相遇
if(pro == last){
return true;
}
}
//循环结束指针没有相遇说明没有环相当于快指针遍历了一遍链表
return false;
}
}
```
其它语言的代码请参考[这里](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode141%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8.md)
判断链表是不是含有环很简单但是我们想找到环的入口可能就没有那么容易了入口则为下图绿色节点 判断链表是不是含有环很简单但是我们想找到环的入口可能就没有那么容易了入口则为下图绿色节点
@ -100,11 +72,15 @@ public:
ListNode *detectCycle(ListNode *head) { ListNode *detectCycle(ListNode *head) {
if (head == nullptr) return head; if (head == nullptr) return head;
if (head->next == nullptr) return head->next; if (head->next == nullptr) return head->next;
//创建新的HashSet用于保存节点
set<ListNode *> hash; set<ListNode *> hash;
//遍历链表
while (head != nullptr) { while (head != nullptr) {
//判断哈希表中是否含有某节点没有则保存含有则返回该节点
if (hash.count(head)) { if (hash.count(head)) {
return head; return head;
} }
//不含有则进行保存并移动指针
hash.insert(head); hash.insert(head);
head = head->next; head = head->next;
} }
@ -137,7 +113,7 @@ var detectCycle = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def detectCycle(self, head: ListNode) -> ListNode: def detectCycle(self, head: ListNode) -> ListNode:
if head is None: if head is None:
@ -253,17 +229,22 @@ JS Code:
```js ```js
var detectCycle = function(head) { var detectCycle = function(head) {
//快慢指针
let fast = head; let fast = head;
let slow = head; let slow = head;
//设置循环条件
while (fast && fast.next) { while (fast && fast.next) {
fast = fast.next.next; fast = fast.next.next;
slow = slow.next; slow = slow.next;
//相遇
if (fast == slow) { if (fast == slow) {
let newptr = head; let newptr = head;
//设置一个新的指针从头节点出发慢指针速度为1所以可以使用慢指针从相遇点出发
while (newptr != slow) { while (newptr != slow) {
slow = slow.next; slow = slow.next;
newptr = newptr.next; newptr = newptr.next;
} }
//在环入口相遇
return slow; return slow;
} }
} }
@ -273,7 +254,7 @@ var detectCycle = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def detectCycle(self, head: ListNode) -> ListNode: def detectCycle(self, head: ListNode) -> ListNode:
# 快慢指针 # 快慢指针

View File

@ -8,7 +8,7 @@
[绘图解析链表详解](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E5%85%B3%E4%BA%8E%E9%93%BE%E8%A1%A8%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B.md) [绘图解析链表详解](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E5%85%B3%E4%BA%8E%E9%93%BE%E8%A1%A8%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B.md)
另外大家如果忘记了[动画模拟插入排序](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E7%9B%B4%E6%8E%A5%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F.md)[动画模拟归并排序](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F.md)思想的话可以先复习一下不然这两道题目会看云里雾里 另外大家如果忘记了[动画模拟插入排序](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E7%9B%B4%E6%8E%A5%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F.md)[动画模拟归并排序](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F.md)思想的话可以先复习一下不然这两道题目会看云里雾里
#### [147. 对链表进行插入排序](https://leetcode-cn.com/problems/insertion-sort-list/) #### [147. 对链表进行插入排序](https://leetcode-cn.com/problems/insertion-sort-list/)
@ -30,7 +30,7 @@
我们的指针在数组时可以随意的前后移动将指针指向值和新元素的值比较后将新元素插入到合适的位置 我们的指针在数组时可以随意的前后移动将指针指向值和新元素的值比较后将新元素插入到合适的位置
我们知道链表查询元素的时间复杂度为 On,我们只能够通过遍历链表查询元素 我们知道链表查询元素的时间复杂度为O(n)我们只能够通过遍历链表查询元素
那么我们怎么才能将新元素放到合适的位置呢见下图 那么我们怎么才能将新元素放到合适的位置呢见下图
@ -68,7 +68,7 @@
我们想要将 3 插入到 2 4 的中间此时我们三个指针分别指向 243 我们想要将 3 插入到 2 4 的中间此时我们三个指针分别指向 243
我们共分 4 来完成这个操作见下图 我们共分 4 来完成这个操作见下图
![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/44444444.29mvcvs4yrms.png) ![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/44444444.29mvcvs4yrms.png)
@ -143,9 +143,9 @@ public:
continue; continue;
} }
//开始出发查找新元素的合适位置 //开始出发查找新元素的合适位置
temphead = dummyNode; ListNode * temphead = dummyNode;
while (temphead->next->val <= pre->val) { while (temphead->next->val <= pre->val) {
ListNode * temphead = temphead->next; temphead = temphead->next;
} }
//此时我们已经找到了合适位置我们需要进行插入大家可以画一画 //此时我们已经找到了合适位置我们需要进行插入大家可以画一画
last->next = pre->next; last->next = pre->next;
@ -195,7 +195,7 @@ var insertionSortList = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def insertionSortList(self, head: ListNode) -> ListNode: def insertionSortList(self, head: ListNode) -> ListNode:
if head is None or head.next is None: if head is None or head.next is None:

View File

@ -1,6 +1,12 @@
> 如果阅读时发现错误或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** 备注 github + 题目 + 问题 向我反馈
>
> 感谢支持该仓库会一直维护希望对各位有一丢丢帮助
>
> 另外希望手机阅读的同学可以来我的 <u>[**公众号袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步想要和题友一起刷题互相监督的同学可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入
今天咱们说一道非常简单但是很经典的面试题思路很容易但是里面细节挺多所以我们还是需要注意 今天咱们说一道非常简单但是很经典的面试题思路很容易但是里面细节挺多所以我们还是需要注意
我们先来看一下题目描述 我们先来看一下题目描述
#### [206. 反转链表](https://leetcode-cn.com/problems/reverse-linked-list/) #### [206. 反转链表](https://leetcode-cn.com/problems/reverse-linked-list/)
@ -19,9 +25,9 @@
原理很容易理解我们首先将 low 指针指向空节点 pro 节点指向 head 节点 原理很容易理解我们首先将 low 指针指向空节点 pro 节点指向 head 节点
然后我们定义一个临时节点指向 pro 节点 然后我们定义一个临时节点 temp 指向 pro 节点
此时我们就记住了 pro 节点的位置然后 pro = pro.next.这样我们三个指针指向三个不同的节点 此时我们就记住了 pro 节点的位置然后 pro = pro.next这样我们三个指针指向三个不同的节点
则我们将 temp 指针指向 low 节点此时则完成了反转 则我们将 temp 指针指向 low 节点此时则完成了反转
@ -59,29 +65,6 @@ class Solution {
} }
} }
``` ```
JS Code:
```javascript
var reverseList = function(head) {
//特殊情况
if(!head || !head.next) {
return head;
}
let low = null;
let pro = head;
while (pro) {
//代表橙色指针
let temp = pro;
//移动绿色指针
pro = pro.next;
//反转节点
temp.next = low;
//移动黄色指针
low = temp;
}
return low;
};
```
C++ Code: C++ Code:
```cpp ```cpp
@ -109,12 +92,36 @@ public:
}; };
``` ```
JS Code:
```javascript
var reverseList = function(head) {
//特殊情况
if(!head || !head.next) {
return head;
}
let low = null;
let pro = head;
while (pro) {
//代表橙色指针
let temp = pro;
//移动绿色指针
pro = pro.next;
//反转节点
temp.next = low;
//移动黄色指针
low = temp;
}
return low;
};
```
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def reverseList(self, head: ListNode) -> ListNode: def reverseList(self, head: ListNode) -> ListNode:
//特殊情况 # 特殊情况
if head is None or head.next is None: if head is None or head.next is None:
return head return head
low = None low = None
@ -147,8 +154,8 @@ class Solution {
} }
//保存最后一个节点 //保存最后一个节点
ListNode pro = reverseList(head.next); ListNode pro = reverseList(head.next);
//将节点进行反转我们可以这样理解 4.next.next = 4; //将节点进行反转我们可以这样理解 4.next.next = 4
//4.next = 5 //4.next = 5
// 5.next = 4 则实现了反转 // 5.next = 4 则实现了反转
head.next.next = head; head.next.next = head;
//防止循环 //防止循环
@ -156,29 +163,9 @@ class Solution {
return pro; return pro;
} }
} }
``` ```
JS Code: C++ Code:
```javascript
var reverseList = function(head) {
//结束条件
if (!head || !head.next) {
return head;
}
//保存最后一个节点
let pro = reverseList(head.next);
//将节点进行反转我们可以这样理解 4.next.next = 4;
//4.next = 5
// 5.next = 4 则实现了反转
head.next.next = head;
//防止循环
head.next = null;
return pro;
};
```
C++代码:
```cpp ```cpp
class Solution { class Solution {
@ -190,8 +177,8 @@ public:
} }
//保存最后一个节点 //保存最后一个节点
ListNode * pro = reverseList(head->next); ListNode * pro = reverseList(head->next);
//将节点进行反转我们可以这样理解 4->next->next = 4; //将节点进行反转我们可以这样理解 4->next->next = 4
//4->next = 5 //4->next = 5
// 5->next = 4 则实现了反转 // 5->next = 4 则实现了反转
head->next->next = head; head->next->next = head;
//防止循环 //防止循环
@ -201,9 +188,29 @@ public:
}; };
``` ```
JS Code:
```javascript
var reverseList = function(head) {
//结束条件
if (!head || !head.next) {
return head;
}
//保存最后一个节点
let pro = reverseList(head.next);
//将节点进行反转我们可以这样理解 4.next.next = 4
//4.next = 5
// 5.next = 4 则实现了反转
head.next.next = head;
//防止循环
head.next = null;
return pro;
};
```
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def reverseList(self, head: ListNode) -> ListNode: def reverseList(self, head: ListNode) -> ListNode:
# 结束条件 # 结束条件
@ -211,8 +218,8 @@ class Solution:
return head return head
# 保存最后一个节点 # 保存最后一个节点
pro = self.reverseList(head.next) pro = self.reverseList(head.next)
# 将节点进行反转我们可以这样理解 4->next->next = 4; # 将节点进行反转我们可以这样理解 4->next->next = 4
# 4->next = 5 # 4->next = 5
# 5->next = 4 则实现了反转 # 5->next = 4 则实现了反转
head.next.next = head head.next.next = head
# 防止循环 # 防止循环
@ -224,9 +231,9 @@ class Solution:
> 贡献者[@jaredliw](https://github.com/jaredliw) > 贡献者[@jaredliw](https://github.com/jaredliw)
> >
> 这里提供一个比较直观的递归写法供大家参考 > 这里提供一个比较直观的递归写法供大家参考由于代码比较直白其它语言的我就不写啦
> >
> ```py > ```python
> class Solution: > class Solution:
> def reverseList(self, head: ListNode, prev_nd: ListNode = None) -> ListNode: > def reverseList(self, head: ListNode, prev_nd: ListNode = None) -> ListNode:
> # 结束条件 > # 结束条件

View File

@ -26,7 +26,7 @@
#### 题目解析 #### 题目解析
题目也很容易理解就是让我们将原来奇数位的结点放一起偶数位的结点放一起这里需要注意和结点值无关是奇数位和偶数位结点 题目也很容易理解就是让我们将原来奇数位的结点放一起偶数位的结点放一起这里需要注意题目和结点值无关是奇数位和偶数位结点
我们可以先将奇数位和在一起再将偶数位和在一起最后再将两个链表合并很简单我们直接看动画模拟吧 我们可以先将奇数位和在一起再将偶数位和在一起最后再将两个链表合并很简单我们直接看动画模拟吧
@ -109,7 +109,7 @@ var oddEvenList = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def oddEvenList(self, head: ListNode) -> ListNode: def oddEvenList(self, head: ListNode) -> ListNode:
if head is None or head.next is None: if head is None or head.next is None:

View File

@ -48,9 +48,9 @@ class Solution {
public ListNode deleteDuplicates(ListNode head) { public ListNode deleteDuplicates(ListNode head) {
//侦察兵指针 //侦察兵指针
ListNode pre = head; ListNode pre = head;
//创建虚拟头节点接上head //创建节点接上head
ListNode dummy = new ListNode(-1); ListNode dummy = new ListNode(-1);
dummy.next = pre; dummy.next = head;
//跟随的指针 //跟随的指针
ListNode low = dummy; ListNode low = dummy;
while(pre != null && pre.next != null) { while(pre != null && pre.next != null) {
@ -82,9 +82,9 @@ public:
ListNode* deleteDuplicates(ListNode* head) { ListNode* deleteDuplicates(ListNode* head) {
//侦察兵指针 //侦察兵指针
ListNode * pre = head; ListNode * pre = head;
//创建虚拟头节点接上head //创建节点接上head
ListNode * dummy = new ListNode(-1 head); ListNode * dummy = new ListNode(-1);
dummy->next = pre; dummy->next = head;
//跟随的指针 //跟随的指针
ListNode * low = dummy; ListNode * low = dummy;
while(pre != nullptr && pre->next != nullptr) { while(pre != nullptr && pre->next != nullptr) {
@ -141,7 +141,7 @@ var deleteDuplicates = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode: def deleteDuplicates(self, head: ListNode) -> ListNode:
# 侦察兵指针 # 侦察兵指针
@ -162,6 +162,6 @@ class Solution:
else: else:
pre = pre.next pre = pre.next
low = low.next low = low.next
return low.next # 注意这里传回的不是head而是虚拟节点的下一个节点head有可能已经换了 return dummy.next # 注意这里传回的不是head而是虚拟节点的下一个节点head有可能已经换了
``` ```

View File

@ -131,12 +131,7 @@ var partition = function(head, x) {
Python Code: Python Code:
```py ```python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution: class Solution:
def partition(self, head: ListNode, x: int) -> ListNode: def partition(self, head: ListNode, x: int) -> ListNode:
pro = head pro = head
@ -161,3 +156,4 @@ class Solution:
small.next = headbig.next small.next = headbig.next
return headsmall.next return headsmall.next
``` ```

View File

@ -4,14 +4,12 @@
> >
> 另外希望手机阅读的同学可以来我的 <u>[**公众号袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步想要和题友一起刷题互相监督的同学可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入 > 另外希望手机阅读的同学可以来我的 <u>[**公众号袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步想要和题友一起刷题互相监督的同学可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入
今天我们来说一下反转链表 2其实这个和 1 的思路差不多今天先说一个比较好理解的方法完全按照反转链表 1 的方法来解决大家看这个题目之前要先看一下[动画模拟leetcode 206 反转链表](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode206%E5%8F%8D%E8%BD%AC%E9%93%BE%E8%A1%A8.md) 今天我们来说一下反转链表 2其实这个和 1 的思路差不多今天先说一个比较好理解的方法完全按照反转链表 1 的方法来解决大家看这个题目之前要先看一下[动画模拟leetcode 206 反转链表](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode206%E5%8F%8D%E8%BD%AC%E9%93%BE%E8%A1%A8.md)
下面我们先来看一下题目 下面我们先来看一下题目
#### [92. 反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) #### [92. 反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/)
难度中等836
给你单链表的头指针 `head` 和两个整数 `left` `right` 其中 `left <= right` 请你反转从位置 `left` 到位置 `right` 的链表节点返回 **反转后的链表** 给你单链表的头指针 `head` 和两个整数 `left` `right` 其中 `left <= right` 请你反转从位置 `left` 到位置 `right` 的链表节点返回 **反转后的链表**
**示例 1** **示例 1**
@ -166,7 +164,6 @@ var reverseBetween = function(head, left, right) {
return temp.next; return temp.next;
}; };
//和反转链表1代码一致 //和反转链表1代码一致
var reverse = function(head) { var reverse = function(head) {
let low = null; let low = null;
@ -183,7 +180,7 @@ var reverse = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode: def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
# 虚拟头节点 # 虚拟头节点

View File

@ -6,7 +6,7 @@
#### [剑指 Offer 25. 合并两个排序的链表](https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/) #### [剑指 Offer 25. 合并两个排序的链表](https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/)
将两个升序链表合并为一个新的 升序 链表并返回新链表是通过拼接给定的两个链表的所有节点组成的 将两个升序链表合并为一个新的 **升序** 链表并返回新链表是通过拼接给定的两个链表的所有节点组成的
示例 示例
@ -105,7 +105,7 @@ var mergeTwoLists = function(l1, l2) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
headpro = ListNode(-1) headpro = ListNode(-1)

View File

@ -115,7 +115,7 @@ var getIntersectionNode = function(headA, headB) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
tempa = headA tempa = headA
@ -207,7 +207,7 @@ var getIntersectionNode = function(headA, headB) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
# 定义两个节点 # 定义两个节点

View File

@ -12,13 +12,13 @@
题目分析 题目分析
自己思考一下 自己思考一下
我们遇到这个题目可能会有什么答题思路呢 我们遇到这个题目可能会有什么答题思路呢
你看我说的对不对是不是会想到先遍历一遍链表知道 链表节点的个数然后再计算出倒数第n个节点 你看我说的对不对是不是会想到先遍历一遍链表知道 链表节点的个数然后再计算出倒数第n个节点
比如链表长度为10倒数第3个节点不就是正数第8个节点呀这种方法当然可以啦是可以实现的那么我们再思考一下有没有其他方法呢我们可以将链表元素保存到数组里面然后直接就可以知道倒数第K个节点了这个方法确实比刚才那个方法省时间了但是所耗的空间更多了那我们还有什么方法吗 比如链表长度为10倒数第3个节点不就是正数第8个节点呀这种方法当然可以啦是可以实现的那么我们再思考一下有没有其他方法呢我们可以将链表元素保存到数组里面然后直接就可以知道倒数第k个节点了这个方法确实比刚才那个方法省时间了但是所耗的空间更多了那我们还有什么方法吗
我们可以继续利用我们的双指针呀但是我们应该怎么做呢 我们可以继续利用我们的双指针呀但是我们应该怎么做呢

View File

@ -17,7 +17,7 @@
输出3 输出3
``` ```
> 说明因为只有一个中间节点 > 说明因为只有一个中间节点
**示例 2** **示例 2**
@ -26,9 +26,9 @@
输出4 输出4
``` ```
> 说明有两个中间节点所以返回后面那个 > 说明有两个中间节点所以返回后面那个
## 题目解析 **题目解析**
又精心筛选了一个题目本来想写一下删除节点的题目然后发现这个题目更符合目前的节奏所以先写一下这个题目明天再给大家写删除节点的题目 又精心筛选了一个题目本来想写一下删除节点的题目然后发现这个题目更符合目前的节奏所以先写一下这个题目明天再给大家写删除节点的题目
@ -44,7 +44,7 @@
一个指针走的快一个指针走的慢这个题目我们可以让快指针一次走两步慢指针一次走一步当快指针到达链表尾部的时候慢指针不就到达中间节点了吗 一个指针走的快一个指针走的慢这个题目我们可以让快指针一次走两步慢指针一次走一步当快指针到达链表尾部的时候慢指针不就到达中间节点了吗
链表中节点的个数有可能为奇数也有可能为偶数这是两种情况但是我们输出是相同的那就是输出slow指针指向的节点 链表中节点的个数有可能为奇数也有可能为偶数这是两种情况但是我们输出是相同的那就是输出 slow 指针指向的节点也就是两个中间节点的第二个
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210321131249789.gif) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210321131249789.gif)
@ -105,7 +105,7 @@ var middleNode = function(head) {
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def middleNode(self, head: ListNode) -> ListNode: def middleNode(self, head: ListNode) -> ListNode:
fast = head # 快指针 fast = head # 快指针

View File

@ -30,14 +30,14 @@
示例2 示例2
```java ```java
输入(9 -> 9) + (9 -> 9),即99+99 输入(9 -> 9) + (9 -> 9) 99 + 99
输出8 -> 9 -> 1 输出8 -> 9 -> 1
``` ```
示例3 示例3
```java ```java
输入(5)+(5),即5+5 输入(5) + (5) 5 + 5
输出0 -> 1 输出0 -> 1
``` ```
@ -79,7 +79,7 @@ Java Code:
class Solution { class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//待会儿要返回的链表 //待会儿要返回的链表
ListNode nList = new ListNode(-1);//虚拟头节点 ListNode nList = new ListNode(-1);//节点
ListNode tempnode = nList; ListNode tempnode = nList;
//用来保存进位值初始化为0 //用来保存进位值初始化为0
int summod = 0; int summod = 0;
@ -109,7 +109,7 @@ class Solution {
if (summod != 0) { if (summod != 0) {
tempnode.next = new ListNode(summod); tempnode.next = new ListNode(summod);
} }
return nList.next;//去除-1节点 return nList.next;//去除节点
} }
} }
``` ```
@ -121,7 +121,7 @@ class Solution {
public: public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
//待会儿要返回的链表 //待会儿要返回的链表
ListNode * nList = new ListNode(-1);//虚拟头节点 ListNode * nList = new ListNode(-1);//节点
ListNode * tempnode = nList; ListNode * tempnode = nList;
//用来保存进位值初始化为0 //用来保存进位值初始化为0
int summod = 0; int summod = 0;
@ -134,7 +134,7 @@ public:
int sum = l1num + l2num + summod; int sum = l1num + l2num + summod;
//更新进位值例18/10=19/10=0 //更新进位值例18/10=19/10=0
summod = sum / 10; summod = sum / 10;
//新节点保存的值1 %8=2则添加2 //新节点保存的值18%8=2则添加2
sum = sum % 10; sum = sum % 10;
//添加节点 //添加节点
tempnode->next = new ListNode(sum); tempnode->next = new ListNode(sum);
@ -151,7 +151,7 @@ public:
if (summod != 0) { if (summod != 0) {
tempnode->next = new ListNode(summod); tempnode->next = new ListNode(summod);
} }
return nList->next;//去除-1节点 return nList->next;//节点
} }
}; };
``` ```
@ -161,7 +161,7 @@ JS Code:
```js ```js
var addTwoNumbers = function(l1, l2) { var addTwoNumbers = function(l1, l2) {
//待会儿要返回的链表 //待会儿要返回的链表
let nList = new ListNode(-1);//虚拟头节点 let nList = new ListNode(-1);//节点
let tempnode = nList; let tempnode = nList;
//用来保存进位值初始化为0 //用来保存进位值初始化为0
let summod = 0; let summod = 0;
@ -174,7 +174,7 @@ var addTwoNumbers = function(l1, l2) {
let sum = l1num + l2num + summod; let sum = l1num + l2num + summod;
//更新进位值例18/10=19/10=0 //更新进位值例18/10=19/10=0
summod = ~~(sum / 10); summod = ~~(sum / 10);
//新节点保存的值1 %8=2则添加2 //新节点保存的值18%8=2则添加2
sum = sum % 10; sum = sum % 10;
//添加节点 //添加节点
tempnode.next = new ListNode(sum); tempnode.next = new ListNode(sum);
@ -191,21 +191,21 @@ var addTwoNumbers = function(l1, l2) {
if (summod !== 0) { if (summod !== 0) {
tempnode.next = new ListNode(summod); tempnode.next = new ListNode(summod);
} }
return nList.next;//去除-1节点 return nList.next;//去除节点
}; };
``` ```
Python Code: Python Code:
```py ```python
class Solution: class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
# 待会儿要返回的链表 # 待会儿要返回的链表
nList = ListNode(-1) # 虚拟头节点 nList = ListNode(-1) # 节点
tempnode = nList tempnode = nList
# 用来保存进位值初始化为0 # 用来保存进位值初始化为0
summod = 0 summod = 0
while l1 is not None and l2 is not None: while l1 is not None o l2 is not None:
# 如果l1的链表为空则l1num为0若是不为空则为链表的节点值 # 如果l1的链表为空则l1num为0若是不为空则为链表的节点值
# 判断是否为空为空就设为0 # 判断是否为空为空就设为0
l1num = 0 if l1 is None else l1.val l1num = 0 if l1 is None else l1.val
@ -227,6 +227,6 @@ class Solution:
# 最后根据进位值判断需不需要继续添加节点 # 最后根据进位值判断需不需要继续添加节点
if summod != 0: if summod != 0:
tempnode.next = ListNode(summod) tempnode.next = ListNode(summod)
return nList.next # 去除-1节点 return nList.next # 去除节点
``` ```