mirror of
https://github.com/chefyuan/algorithm-base.git
synced 2025-08-02 05:51:34 +00:00
代码重构 【Github Actions】
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [234. 回文链表](https://leetcode-cn.com/problems/palindrome-linked-list/)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
输出: false
|
||||
```
|
||||
|
||||
|
||||
示例 2:
|
||||
|
||||
```java
|
||||
@@ -25,7 +24,7 @@
|
||||
|
||||
题目解析:
|
||||
|
||||
题目理解起来很简单,判断是否为回文,如果单纯判断一个字符串或者数组是不是回文很容易。因为数组查询元素的时间复杂度为O(1),但是链表的查询时间复杂度为O(n),而且题目中的链表为单链表,指针只能后移不能前移。所以我们判断起来会比较困难。
|
||||
题目理解起来很简单,判断是否为回文,如果单纯判断一个字符串或者数组是不是回文很容易。因为数组查询元素的时间复杂度为 O(1),但是链表的查询时间复杂度为 O(n),而且题目中的链表为单链表,指针只能后移不能前移。所以我们判断起来会比较困难。
|
||||
|
||||
巧用数组法:
|
||||
|
||||
@@ -97,27 +96,27 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var isPalindrome = function(head) {
|
||||
let arr = [];
|
||||
let copynode = head;
|
||||
//将链表的值复制到数组中
|
||||
while (copynode) {
|
||||
arr.push(copynode.val)
|
||||
copynode = copynode.next
|
||||
var isPalindrome = function (head) {
|
||||
let arr = [];
|
||||
let copynode = head;
|
||||
//将链表的值复制到数组中
|
||||
while (copynode) {
|
||||
arr.push(copynode.val);
|
||||
copynode = copynode.next;
|
||||
}
|
||||
//双指针遍历数组
|
||||
let back = 0;
|
||||
let pro = arr.length - 1;
|
||||
while (back < pro) {
|
||||
//判断两个指针的值是否相等
|
||||
if (arr[back] !== arr[pro]) {
|
||||
return false;
|
||||
}
|
||||
//双指针遍历数组
|
||||
let back = 0;
|
||||
let pro = arr.length - 1;
|
||||
while (back < pro) {
|
||||
//判断两个指针的值是否相等
|
||||
if (arr[back] !== arr[pro]) {
|
||||
return false
|
||||
}
|
||||
//移动指针
|
||||
back += 1
|
||||
pro -= 1
|
||||
}
|
||||
return true
|
||||
//移动指针
|
||||
back += 1;
|
||||
pro -= 1;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -202,7 +201,7 @@ class Solution {
|
||||
ListNode backhalf = reverse(midnode.next);
|
||||
//遍历两部分链表,判断值是否相等
|
||||
ListNode p1 = head;
|
||||
ListNode p2 = backhalf;
|
||||
ListNode p2 = backhalf;
|
||||
while (p2 != null) {
|
||||
if (p1.val != p2.val) {
|
||||
//若要还原,记得这里也要reverse
|
||||
@@ -211,11 +210,11 @@ class Solution {
|
||||
}
|
||||
p1 = p1.next;
|
||||
p2 = p2.next;
|
||||
}
|
||||
}
|
||||
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
|
||||
//当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
|
||||
midnode.next = reverse(backhalf);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
//找到中点
|
||||
public ListNode searchmidnode (ListNode head) {
|
||||
@@ -224,7 +223,7 @@ class Solution {
|
||||
while (fast.next != null && fast.next.next != null) {
|
||||
fast = fast.next.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
//翻转链表
|
||||
@@ -259,7 +258,7 @@ public:
|
||||
ListNode * backhalf = reverse(midnode->next);
|
||||
//遍历两部分链表,判断值是否相等
|
||||
ListNode * p1 = head;
|
||||
ListNode * p2 = backhalf;
|
||||
ListNode * p2 = backhalf;
|
||||
while (p2 != nullptr) {
|
||||
if (p1->val != p2->val) {
|
||||
//若要还原,记得这里也要reverse
|
||||
@@ -268,11 +267,11 @@ public:
|
||||
}
|
||||
p1 = p1->next;
|
||||
p2 = p2->next;
|
||||
}
|
||||
}
|
||||
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
|
||||
//当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
|
||||
midnode->next = reverse(backhalf);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
//找到中间的部分
|
||||
ListNode * searchmidnode (ListNode * head) {
|
||||
@@ -281,7 +280,7 @@ public:
|
||||
while (fast->next != nullptr && fast->next->next != nullptr) {
|
||||
fast = fast->next->next;
|
||||
slow = slow->next;
|
||||
}
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
//翻转链表
|
||||
@@ -302,56 +301,56 @@ public:
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var isPalindrome = function(head) {
|
||||
if (head === null || head.next === null) {
|
||||
return true;
|
||||
}
|
||||
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
|
||||
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
|
||||
let midnode = searchmidnode(head);
|
||||
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
|
||||
//这里我们用的是midnode.next需要注意,因为我们找到的是中点,但是我们翻转的是后半部分
|
||||
let backhalf = reverse(midnode.next);
|
||||
//遍历两部分链表,判断值是否相等
|
||||
let p1 = head;
|
||||
let p2 = backhalf;
|
||||
while (p2 != null) {
|
||||
if (p1.val != p2.val) {
|
||||
//若要还原,记得这里也要reverse
|
||||
midnode.next = reverse(backhalf);
|
||||
return false;
|
||||
}
|
||||
p1 = p1.next;
|
||||
p2 = p2.next;
|
||||
}
|
||||
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
|
||||
//当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
|
||||
midnode.next = reverse(backhalf);
|
||||
var isPalindrome = function (head) {
|
||||
if (head === null || head.next === null) {
|
||||
return true;
|
||||
}
|
||||
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
|
||||
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
|
||||
let midnode = searchmidnode(head);
|
||||
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
|
||||
//这里我们用的是midnode.next需要注意,因为我们找到的是中点,但是我们翻转的是后半部分
|
||||
let backhalf = reverse(midnode.next);
|
||||
//遍历两部分链表,判断值是否相等
|
||||
let p1 = head;
|
||||
let p2 = backhalf;
|
||||
while (p2 != null) {
|
||||
if (p1.val != p2.val) {
|
||||
//若要还原,记得这里也要reverse
|
||||
midnode.next = reverse(backhalf);
|
||||
return false;
|
||||
}
|
||||
p1 = p1.next;
|
||||
p2 = p2.next;
|
||||
}
|
||||
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
|
||||
//当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
|
||||
midnode.next = reverse(backhalf);
|
||||
return true;
|
||||
};
|
||||
|
||||
//找到中点
|
||||
var searchmidnode = function(head) {
|
||||
let fast = head;
|
||||
let slow = head;
|
||||
while (fast.next != null && fast.next.next != null) {
|
||||
fast = fast.next.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
return slow;
|
||||
var searchmidnode = function (head) {
|
||||
let fast = head;
|
||||
let slow = head;
|
||||
while (fast.next != null && fast.next.next != null) {
|
||||
fast = fast.next.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
return slow;
|
||||
};
|
||||
|
||||
//翻转链表
|
||||
var reverse = function(slow) {
|
||||
let low = null;
|
||||
let temp = null;
|
||||
while (slow != null) {
|
||||
temp = slow.next;
|
||||
slow.next = low;
|
||||
low = slow;
|
||||
slow = temp;
|
||||
}
|
||||
return low;
|
||||
var reverse = function (slow) {
|
||||
let low = null;
|
||||
let temp = null;
|
||||
while (slow != null) {
|
||||
temp = slow.next;
|
||||
slow.next = low;
|
||||
low = slow;
|
||||
slow = temp;
|
||||
}
|
||||
return low;
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
### [141. 环形链表](https://leetcode-cn.com/problems/linked-list-cycle/)
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
#### 题目描述
|
||||
|
||||
> 给定一个链表,判断链表中是否有环。pos代表环的入口,若为-1,则代表无环。
|
||||
> 给定一个链表,判断链表中是否有环。pos 代表环的入口,若为-1,则代表无环。
|
||||
>
|
||||
> 如果链表中存在环,则返回 true 。否则,返回 false 。
|
||||
|
||||
示例1:
|
||||
示例 1:
|
||||
|
||||

|
||||
|
||||
@@ -34,11 +34,10 @@
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
public class Solution {
|
||||
public boolean hasCycle(ListNode head) {
|
||||
@@ -79,17 +78,17 @@ 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [142. 环形链表 II](https://leetcode-cn.com/problems/linked-list-cycle-ii/)
|
||||
|
||||
@@ -22,17 +22,15 @@
|
||||
|
||||
判断链表是不是含有环很简单,但是我们想找到环的入口可能就没有那么容易了。(入口则为下图绿色节点)
|
||||
|
||||
然后我们返回的则为绿色节点的索引,则返回2。
|
||||
然后我们返回的则为绿色节点的索引,则返回 2。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### HashSet
|
||||
|
||||
我们可以利用HashSet来做,之前的文章说过HashSet是一个不允许有重复元素的集合。所以我们通过HashSet来保存链表节点,对链表进行遍历,如果链表不存在环则每个节点都会被存入环中,但是当链表中存在环时,则会发重复存储链表节点的情况,所以当我们发现HashSet中含有某节点时说明该节点为环的入口,返回即可。
|
||||
我们可以利用 HashSet 来做,之前的文章说过 HashSet 是一个不允许有重复元素的集合。所以我们通过 HashSet 来保存链表节点,对链表进行遍历,如果链表不存在环则每个节点都会被存入环中,但是当链表中存在环时,则会发重复存储链表节点的情况,所以当我们发现 HashSet 中含有某节点时说明该节点为环的入口,返回即可。
|
||||
|
||||
下图中,存储顺序为 0,1,2,3,4,5,6,**2 **因为2已经存在,则返回。
|
||||
下图中,存储顺序为 0,1,2,3,4,5,6,**2 **因为 2 已经存在,则返回。
|
||||
|
||||

|
||||
|
||||
@@ -58,7 +56,7 @@ public class Solution {
|
||||
//不含有,则进行保存,并移动指针
|
||||
hash.add(head);
|
||||
head = head.next;
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
}
|
||||
@@ -92,22 +90,22 @@ public:
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var detectCycle = function(head) {
|
||||
if (head === null) return head;
|
||||
if (head.next === null) return head.next;
|
||||
//创建新的HashSet,用于保存节点
|
||||
let hash = new Set();
|
||||
//遍历链表
|
||||
while (head !== null) {
|
||||
//判断哈希表中是否含有某节点,没有则保存,含有则返回该节点
|
||||
if (hash.has(head)) {
|
||||
return head;
|
||||
}
|
||||
//不含有,则进行保存,并移动指针
|
||||
hash.add(head);
|
||||
head = head.next;
|
||||
var detectCycle = function (head) {
|
||||
if (head === null) return head;
|
||||
if (head.next === null) return head.next;
|
||||
//创建新的HashSet,用于保存节点
|
||||
let hash = new Set();
|
||||
//遍历链表
|
||||
while (head !== null) {
|
||||
//判断哈希表中是否含有某节点,没有则保存,含有则返回该节点
|
||||
if (hash.has(head)) {
|
||||
return head;
|
||||
}
|
||||
return head;
|
||||
//不含有,则进行保存,并移动指针
|
||||
hash.add(head);
|
||||
head = head.next;
|
||||
}
|
||||
return head;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -140,25 +138,25 @@ class Solution:
|
||||
|
||||
上图黄色节点为快慢指针相遇的节点,此时
|
||||
|
||||
快指针走的距离:**a+(b+c)n+b**,n代表圈数。
|
||||
快指针走的距离:**a+(b+c)n+b**,n 代表圈数。
|
||||
|
||||
很容易理解b+c为环的长度,a为直线距离,b为绕了n圈之后又走了一段距离才相遇,所以相遇时走的总路程为a+(b+c)n+b,合并同类项得a+(n+1)b+nc。
|
||||
很容易理解 b+c 为环的长度,a 为直线距离,b 为绕了 n 圈之后又走了一段距离才相遇,所以相遇时走的总路程为 a+(b+c)n+b,合并同类项得 a+(n+1)b+nc。
|
||||
|
||||
慢指针走的距离:**a+(b+c)m+b**,m代表圈数。
|
||||
慢指针走的距离:**a+(b+c)m+b**,m 代表圈数。
|
||||
|
||||
然后我们设快指针得速度是慢指针的2倍,含义为相同时间内,快指针走过的距离是慢指针的2倍。
|
||||
然后我们设快指针得速度是慢指针的 2 倍,含义为相同时间内,快指针走过的距离是慢指针的 2 倍。
|
||||
|
||||
**a+(n+1)b+nc=2[a+(m+1)b+mc]**整理得**a+b=(n-2m)(b+c),**那么我们可以从这个等式上面发现什么呢?
|
||||
|
||||
**b+c**为一圈的长度。也就是说a+b等于n-2m个环的长度。为了便于理解我们看一种特殊情况,当n-2m等于1,那么a+b=b+c整理得,a=c。此时我们只需重新释放两个指针,一个从head释放,一个从相遇点释放,速度相同,因为a=c所以他俩必会在环入口处相遇,则求得入口节点索引。
|
||||
**b+c**为一圈的长度。也就是说 a+b 等于 n-2m 个环的长度。为了便于理解我们看一种特殊情况,当 n-2m 等于 1,那么 a+b=b+c 整理得,a=c。此时我们只需重新释放两个指针,一个从 head 释放,一个从相遇点释放,速度相同,因为 a=c 所以他俩必会在环入口处相遇,则求得入口节点索引。
|
||||
|
||||
算法流程:
|
||||
|
||||
1.设置快慢指针,快指针速度为慢指针的2倍。
|
||||
1.设置快慢指针,快指针速度为慢指针的 2 倍。
|
||||
|
||||
2.找出相遇点。
|
||||
|
||||
3.在head处和相遇点同时释放相同速度且速度为1的指针,两指针必会在环入口处相遇。
|
||||
3.在 head 处和相遇点同时释放相同速度且速度为 1 的指针,两指针必会在环入口处相遇。
|
||||
|
||||

|
||||
|
||||
@@ -187,7 +185,7 @@ public class Solution {
|
||||
//在环入口相遇
|
||||
return slow;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -217,7 +215,7 @@ public:
|
||||
//在环入口相遇
|
||||
return slow;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
@@ -226,27 +224,27 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var detectCycle = function(head) {
|
||||
//快慢指针
|
||||
let fast = head;
|
||||
let slow = head;
|
||||
//设置循环条件
|
||||
while (fast && fast.next) {
|
||||
fast = fast.next.next;
|
||||
var detectCycle = function (head) {
|
||||
//快慢指针
|
||||
let fast = head;
|
||||
let slow = head;
|
||||
//设置循环条件
|
||||
while (fast && fast.next) {
|
||||
fast = fast.next.next;
|
||||
slow = slow.next;
|
||||
//相遇
|
||||
if (fast == slow) {
|
||||
let newptr = head;
|
||||
//设置一个新的指针,从头节点出发,慢指针速度为1,所以可以使用慢指针从相遇点出发
|
||||
while (newptr != slow) {
|
||||
slow = slow.next;
|
||||
//相遇
|
||||
if (fast == slow) {
|
||||
let newptr = head;
|
||||
//设置一个新的指针,从头节点出发,慢指针速度为1,所以可以使用慢指针从相遇点出发
|
||||
while (newptr != slow) {
|
||||
slow = slow.next;
|
||||
newptr = newptr.next;
|
||||
}
|
||||
//在环入口相遇
|
||||
return slow;
|
||||
}
|
||||
newptr = newptr.next;
|
||||
}
|
||||
//在环入口相遇
|
||||
return slow;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -287,7 +285,7 @@ class Solution {
|
||||
if fast === slow {
|
||||
// 设置一个新的指针,从头节点出发,慢指针速度为1,所以可以使用慢指针从相遇点出发
|
||||
// 此处也可以不创新结点,直接将 fast = head
|
||||
var newNode = head
|
||||
var newNode = head
|
||||
while newNode !== slow {
|
||||
slow = slow?.next
|
||||
newNode = newNode?.next
|
||||
@@ -298,4 +296,4 @@ class Solution {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
有的老哥说链表的排序搞不明白,让我写一下,一不小心给忘记了,今天咱们就安排上。没有学过数据结构的同学可以先看下这个文章:
|
||||
|
||||
@@ -26,11 +26,9 @@
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
我们的指针在数组时,可以随意的前后移动,将指针指向值和新元素的值比较后,将新元素插入到合适的位置。
|
||||
|
||||
我们知道链表查询元素的时间复杂度为O(n),我们只能够通过遍历链表查询元素。
|
||||
我们知道链表查询元素的时间复杂度为 O(n),我们只能够通过遍历链表查询元素。
|
||||
|
||||
那么我们怎么才能将新元素放到合适的位置呢?见下图。
|
||||
|
||||
@@ -46,8 +44,8 @@
|
||||
|
||||
```java
|
||||
while (temphead.next.val <= pre.val) {
|
||||
temphead = temphead.next;
|
||||
}
|
||||
temphead = temphead.next;
|
||||
}
|
||||
```
|
||||
|
||||
下面我们再来看动画模拟具体过程。
|
||||
@@ -60,12 +58,8 @@
|
||||
|
||||
见下图。
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
我们想要将 3 插入到 2 和 4 的中间,此时我们三个指针分别指向 2,4,3。
|
||||
|
||||
我们共分 4 步,来完成这个操作,见下图。
|
||||
@@ -101,12 +95,12 @@ class Solution {
|
||||
pre = pre.next;
|
||||
last = last.next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//开始出发,查找新元素的合适位置
|
||||
ListNode temphead = dummyNode;
|
||||
while (temphead.next.val <= pre.val) {
|
||||
temphead = temphead.next;
|
||||
}
|
||||
}
|
||||
//此时我们已经找到了合适位置,我们需要进行插入,大家可以画一画
|
||||
last.next = pre.next;
|
||||
pre.next = temphead.next;
|
||||
@@ -119,7 +113,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
@@ -141,12 +135,12 @@ public:
|
||||
pre = pre->next;
|
||||
last = last->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//开始出发,查找新元素的合适位置
|
||||
ListNode * temphead = dummyNode;
|
||||
while (temphead->next->val <= pre->val) {
|
||||
temphead = temphead->next;
|
||||
}
|
||||
}
|
||||
//此时我们已经找到了合适位置,我们需要进行插入,大家可以画一画
|
||||
last->next = pre->next;
|
||||
pre->next = temphead->next;
|
||||
@@ -162,34 +156,34 @@ public:
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var insertionSortList = function(head) {
|
||||
if (head === null || head.next === null) return head;
|
||||
//哑节点
|
||||
let dummyNode = new ListNode(-1, head);
|
||||
let pre = head.next;
|
||||
//pre负责指向新元素,last 负责指向新元素的前一元素
|
||||
//判断是否需要执行插入操作
|
||||
let last = head;
|
||||
while (pre) {
|
||||
//不需要插入到合适位置,则继续往下移动
|
||||
if (last.val <= pre.val) {
|
||||
last = last.next;
|
||||
pre = pre.next;
|
||||
continue;
|
||||
}
|
||||
//开始出发,查找新元素的合适位置
|
||||
let tempHead = dummyNode;
|
||||
while (tempHead.next.val <= pre.val) {
|
||||
tempHead = tempHead.next;
|
||||
}
|
||||
//此时我们已经找到了合适位置,我们需要进行插入,大家可以画一画
|
||||
last.next = pre.next;
|
||||
pre.next = tempHead.next;
|
||||
tempHead.next = pre;
|
||||
//继续往下移动
|
||||
pre = last.next;
|
||||
var insertionSortList = function (head) {
|
||||
if (head === null || head.next === null) return head;
|
||||
//哑节点
|
||||
let dummyNode = new ListNode(-1, head);
|
||||
let pre = head.next;
|
||||
//pre负责指向新元素,last 负责指向新元素的前一元素
|
||||
//判断是否需要执行插入操作
|
||||
let last = head;
|
||||
while (pre) {
|
||||
//不需要插入到合适位置,则继续往下移动
|
||||
if (last.val <= pre.val) {
|
||||
last = last.next;
|
||||
pre = pre.next;
|
||||
continue;
|
||||
}
|
||||
return dummyNode.next;
|
||||
//开始出发,查找新元素的合适位置
|
||||
let tempHead = dummyNode;
|
||||
while (tempHead.next.val <= pre.val) {
|
||||
tempHead = tempHead.next;
|
||||
}
|
||||
//此时我们已经找到了合适位置,我们需要进行插入,大家可以画一画
|
||||
last.next = pre.next;
|
||||
pre.next = tempHead.next;
|
||||
tempHead.next = pre;
|
||||
//继续往下移动
|
||||
pre = last.next;
|
||||
}
|
||||
return dummyNode.next;
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
今天咱们说一道非常简单但是很经典的面试题,思路很容易,但是里面细节挺多,所以我们还是需要注意。
|
||||
|
||||
@@ -37,11 +37,10 @@
|
||||
|
||||
我会对每个关键点进行注释,大家可以参考动图理解。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode reverseList(ListNode head) {
|
||||
@@ -60,11 +59,12 @@ class Solution {
|
||||
temp.next = low;
|
||||
//移动黄色指针
|
||||
low = temp;
|
||||
}
|
||||
}
|
||||
return low;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
temp->next = low;
|
||||
//移动黄色指针
|
||||
low = temp;
|
||||
}
|
||||
}
|
||||
return low;
|
||||
}
|
||||
};
|
||||
@@ -95,24 +95,24 @@ 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;
|
||||
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;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -166,11 +166,10 @@ class Solution {
|
||||
|
||||
上面的迭代写法是不是搞懂啦,现在还有一种递归写法,不是特别容易理解,刚开始刷题的同学,可以只看迭代解法。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode reverseList(ListNode head) {
|
||||
@@ -217,20 +216,20 @@ 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;
|
||||
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;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -290,4 +289,3 @@ class Solution {
|
||||
> # 给定下一组该反转的节点
|
||||
> return self.reverseList(next_nd, head)
|
||||
> ```
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
### [328. 奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
示例 2:
|
||||
|
||||
> 输入: 2->1->3->5->6->4->7->NULL
|
||||
> 输入: 2->1->3->5->6->4->7->NULL
|
||||
> 输出: 2->3->6->7->1->5->4->NULL
|
||||
|
||||
#### 题目解析
|
||||
@@ -54,7 +54,7 @@ class Solution {
|
||||
odd = odd.next;
|
||||
even.next = odd.next;
|
||||
even = even.next;
|
||||
}
|
||||
}
|
||||
//链接
|
||||
odd.next = evenHead;
|
||||
return head;
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
odd = odd->next;
|
||||
even->next = odd->next;
|
||||
even = even->next;
|
||||
}
|
||||
}
|
||||
//链接
|
||||
odd->next = evenHead;
|
||||
return head;
|
||||
@@ -90,20 +90,23 @@ public:
|
||||
```
|
||||
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var oddEvenList = function(head) {
|
||||
if(!head || !head.next) return head;
|
||||
let odd = head, even = head.next, evenHead = even;
|
||||
while(odd.next && even.next){
|
||||
//将偶数位合在一起,奇数位合在一起
|
||||
odd.next = even.next;
|
||||
odd = odd.next;
|
||||
even.next = odd.next;
|
||||
even = even.next;
|
||||
}
|
||||
//链接
|
||||
odd.next = evenHead;
|
||||
return head;
|
||||
var oddEvenList = function (head) {
|
||||
if (!head || !head.next) return head;
|
||||
let odd = head,
|
||||
even = head.next,
|
||||
evenHead = even;
|
||||
while (odd.next && even.next) {
|
||||
//将偶数位合在一起,奇数位合在一起
|
||||
odd.next = even.next;
|
||||
odd = odd.next;
|
||||
even.next = odd.next;
|
||||
even = even.next;
|
||||
}
|
||||
//链接
|
||||
odd.next = evenHead;
|
||||
return head;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -151,4 +154,4 @@ class Solution {
|
||||
return head
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [82. 删除排序链表中的重复元素 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
输出: 1->2->5
|
||||
```
|
||||
|
||||
|
||||
示例 2:
|
||||
|
||||
```java
|
||||
@@ -25,7 +24,7 @@
|
||||
输出: 2->3
|
||||
```
|
||||
|
||||
> 注意这里会将重复的值全部删除,1,1,2,3最后只会保留2,3。
|
||||
> 注意这里会将重复的值全部删除,1,1,2,3 最后只会保留 2,3。
|
||||
|
||||
这道题目还是很简单的,更多的是考察大家的代码完整性,删除节点也是题库中的一类题目,我们可以可以通过这个题目举一反三。去完成其他删除阶段的题目。
|
||||
|
||||
@@ -62,7 +61,7 @@ class Solution {
|
||||
//while循环后,pre停留在最后一个重复的节点上
|
||||
pre = pre.next;
|
||||
//连上新节点
|
||||
low.next = pre;
|
||||
low.next = pre;
|
||||
}
|
||||
else{
|
||||
pre = pre.next;
|
||||
@@ -96,7 +95,7 @@ public:
|
||||
//while循环后,pre停留在最后一个重复的节点上
|
||||
pre = pre->next;
|
||||
//连上新节点
|
||||
low->next = pre;
|
||||
low->next = pre;
|
||||
}
|
||||
else{
|
||||
pre = pre->next;
|
||||
@@ -111,31 +110,30 @@ public:
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var deleteDuplicates = function(head) {
|
||||
//侦察兵指针
|
||||
let pre = head;
|
||||
//创建虚拟头节点,接上head
|
||||
let dummy = new ListNode(-1);
|
||||
dummy.next = pre;
|
||||
//跟随的指针
|
||||
let low = dummy;
|
||||
while(pre != null && pre.next != null) {
|
||||
if (pre.val == pre.next.val) {
|
||||
//移动侦察兵指针直到找到与上一个不相同的元素
|
||||
while (pre != null && pre.next != null && pre.val === pre.next.val) {
|
||||
pre = pre.next;
|
||||
}
|
||||
//while循环后,pre停留在最后一个重复的节点上
|
||||
pre = pre.next;
|
||||
//连上新节点
|
||||
low.next = pre;
|
||||
}
|
||||
else{
|
||||
pre = pre.next;
|
||||
low = low.next;
|
||||
}
|
||||
var deleteDuplicates = function (head) {
|
||||
//侦察兵指针
|
||||
let pre = head;
|
||||
//创建虚拟头节点,接上head
|
||||
let dummy = new ListNode(-1);
|
||||
dummy.next = pre;
|
||||
//跟随的指针
|
||||
let low = dummy;
|
||||
while (pre != null && pre.next != null) {
|
||||
if (pre.val == pre.next.val) {
|
||||
//移动侦察兵指针直到找到与上一个不相同的元素
|
||||
while (pre != null && pre.next != null && pre.val === pre.next.val) {
|
||||
pre = pre.next;
|
||||
}
|
||||
//while循环后,pre停留在最后一个重复的节点上
|
||||
pre = pre.next;
|
||||
//连上新节点
|
||||
low.next = pre;
|
||||
} else {
|
||||
pre = pre.next;
|
||||
low = low.next;
|
||||
}
|
||||
return dummy.next;//注意,这里传回的不是head,而是虚拟节点的下一个节点,head有可能已经换了
|
||||
}
|
||||
return dummy.next; //注意,这里传回的不是head,而是虚拟节点的下一个节点,head有可能已经换了
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [86. 分隔链表](https://leetcode-cn.com/problems/partition-list/)
|
||||
|
||||
@@ -10,11 +10,10 @@
|
||||
|
||||
你应当 保留 两个分区中每个节点的初始相对位置。
|
||||
|
||||

|
||||

|
||||
|
||||
示例 1:
|
||||
|
||||
|
||||
输入:head = [1,4,3,2,5,2], x = 3
|
||||
输出:[1,2,2,4,3,5]
|
||||
示例 2:
|
||||
@@ -24,7 +23,7 @@
|
||||
|
||||
来源:力扣(LeetCode)
|
||||
|
||||
这个题目我的做题思路是这样的,我们先创建一个侦察兵,侦察兵负责比较链表值和 x 值,如果 >= 的话则接在 big 链表上,小于则接到 small 链表上,最后一个细节就是我们的 big 链表尾部要加上 null,不然会形成环。这是这个题目的一个小细节,很重要。
|
||||
这个题目我的做题思路是这样的,我们先创建一个侦察兵,侦察兵负责比较链表值和 x 值,如果 >= 的话则接在 big 链表上,小于则接到 small 链表上,最后一个细节就是我们的 big 链表尾部要加上 null,不然会形成环。这是这个题目的一个小细节,很重要。
|
||||
|
||||
中心思想就是,将链表先分后合。
|
||||
|
||||
@@ -41,9 +40,9 @@ class Solution {
|
||||
public ListNode partition(ListNode head, int x) {
|
||||
ListNode pro = head;
|
||||
ListNode big = new ListNode(-1);
|
||||
ListNode small = new ListNode(-1);
|
||||
ListNode headbig = big;
|
||||
ListNode headsmall = small;
|
||||
ListNode small = new ListNode(-1);
|
||||
ListNode headbig = big;
|
||||
ListNode headsmall = small;
|
||||
//分
|
||||
while (pro != null) {
|
||||
//大于时,放到 big 链表上
|
||||
@@ -74,9 +73,9 @@ public:
|
||||
ListNode* partition(ListNode* head, int x) {
|
||||
ListNode * pro = head;
|
||||
ListNode * big = new ListNode(-1);
|
||||
ListNode * small = new ListNode(-1);
|
||||
ListNode * headbig = big;
|
||||
ListNode * headsmall = small;
|
||||
ListNode * small = new ListNode(-1);
|
||||
ListNode * headbig = big;
|
||||
ListNode * headsmall = small;
|
||||
//分
|
||||
while (pro != nullptr) {
|
||||
//大于时,放到 big 链表上
|
||||
@@ -102,30 +101,30 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var partition = function(head, x) {
|
||||
let pro = head;
|
||||
let big = new ListNode(-1);
|
||||
let small = new ListNode(-1);
|
||||
let headbig = big;
|
||||
let headsmall = small;
|
||||
//分
|
||||
while (pro) {
|
||||
//大于时,放到 big 链表上
|
||||
if (pro.val >= x) {
|
||||
big.next = pro;
|
||||
big = big.next;
|
||||
//小于时,放到 small 链表上
|
||||
}else {
|
||||
small.next = pro;
|
||||
small = small.next;
|
||||
}
|
||||
pro = pro.next;
|
||||
var partition = function (head, x) {
|
||||
let pro = head;
|
||||
let big = new ListNode(-1);
|
||||
let small = new ListNode(-1);
|
||||
let headbig = big;
|
||||
let headsmall = small;
|
||||
//分
|
||||
while (pro) {
|
||||
//大于时,放到 big 链表上
|
||||
if (pro.val >= x) {
|
||||
big.next = pro;
|
||||
big = big.next;
|
||||
//小于时,放到 small 链表上
|
||||
} else {
|
||||
small.next = pro;
|
||||
small = small.next;
|
||||
}
|
||||
//细节
|
||||
big.next = null;
|
||||
//合
|
||||
small.next = headbig.next;
|
||||
return headsmall.next;
|
||||
pro = pro.next;
|
||||
}
|
||||
//细节
|
||||
big.next = null;
|
||||
//合
|
||||
small.next = headbig.next;
|
||||
return headsmall.next;
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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)。
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
|
||||
是不是很容易理解,下面我们来看代码吧。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
@@ -78,7 +76,7 @@ class Solution {
|
||||
pro = pro.next;
|
||||
temp.next = low;
|
||||
low = temp;
|
||||
}
|
||||
}
|
||||
return low;
|
||||
}
|
||||
}
|
||||
@@ -126,7 +124,7 @@ public:
|
||||
pro = pro->next;
|
||||
temp->next = low;
|
||||
low = temp;
|
||||
}
|
||||
}
|
||||
return low;
|
||||
}
|
||||
};
|
||||
@@ -135,46 +133,46 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var reverseBetween = function(head, left, right) {
|
||||
//虚拟头节点
|
||||
let temp = new ListNode(-1);
|
||||
temp.next = head;
|
||||
let pro = temp;
|
||||
//来到 left 节点前的一个节点
|
||||
let i = 0;
|
||||
for (; i < left-1; ++i) {
|
||||
pro = pro.next;
|
||||
}
|
||||
//保存 left 节点前的一个节点
|
||||
let leftNode = pro;
|
||||
//来到 right 节点
|
||||
for (; i < right; ++i) {
|
||||
pro = pro.next;
|
||||
}
|
||||
//保存 right 节点后的一个节点
|
||||
let rightNode = pro.next;
|
||||
//切断链表
|
||||
pro.next = null;//切断 right 后的部分
|
||||
let newhead = leftNode.next;//保存 left 节点
|
||||
leftNode.next = null;//切断 left 前的部分
|
||||
//反转
|
||||
leftNode.next = reverse(newhead);
|
||||
//重新接头
|
||||
newhead.next = rightNode;
|
||||
return temp.next;
|
||||
var reverseBetween = function (head, left, right) {
|
||||
//虚拟头节点
|
||||
let temp = new ListNode(-1);
|
||||
temp.next = head;
|
||||
let pro = temp;
|
||||
//来到 left 节点前的一个节点
|
||||
let i = 0;
|
||||
for (; i < left - 1; ++i) {
|
||||
pro = pro.next;
|
||||
}
|
||||
//保存 left 节点前的一个节点
|
||||
let leftNode = pro;
|
||||
//来到 right 节点
|
||||
for (; i < right; ++i) {
|
||||
pro = pro.next;
|
||||
}
|
||||
//保存 right 节点后的一个节点
|
||||
let rightNode = pro.next;
|
||||
//切断链表
|
||||
pro.next = null; //切断 right 后的部分
|
||||
let newhead = leftNode.next; //保存 left 节点
|
||||
leftNode.next = null; //切断 left 前的部分
|
||||
//反转
|
||||
leftNode.next = reverse(newhead);
|
||||
//重新接头
|
||||
newhead.next = rightNode;
|
||||
return temp.next;
|
||||
};
|
||||
|
||||
//和反转链表1代码一致
|
||||
var reverse = function(head) {
|
||||
let low = null;
|
||||
let pro = head;
|
||||
while (pro) {
|
||||
let temp = pro;
|
||||
pro = pro.next;
|
||||
temp.next = low;
|
||||
low = temp;
|
||||
}
|
||||
return low;
|
||||
var reverse = function (head) {
|
||||
let low = null;
|
||||
let pro = head;
|
||||
while (pro) {
|
||||
let temp = pro;
|
||||
pro = pro.next;
|
||||
temp.next = low;
|
||||
low = temp;
|
||||
}
|
||||
return low;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -205,7 +203,7 @@ class Solution:
|
||||
# 重新接头
|
||||
newhead.next = rightNode
|
||||
return temp.next
|
||||
|
||||
|
||||
# 和反转链表1代码一致
|
||||
def reverse(self, head):
|
||||
low = None
|
||||
@@ -264,4 +262,4 @@ class Solution {
|
||||
return low
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
@@ -1,12 +1,12 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [剑指 Offer 25. 合并两个排序的链表](https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/)
|
||||
|
||||
将两个升序链表合并为一个新的 **升序** 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
|
||||
将两个升序链表合并为一个新的 **升序** 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
|
||||
|
||||
示例:
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
输出:1->1->2->3->4->4
|
||||
```
|
||||
|
||||
今天的题目思路很简单,但是一遍AC也是不容易的。链表大部分题目考察的都是考生代码的完整性和鲁棒性,所以有些题目我们看着思路很简单,但是想直接通过还是需要下一翻工夫的,所以建议大家将所有链表的题目都自己写一下。实在没有时间做的同学,可以自己在脑子里打一遍代码,想清每一行代码的作用。
|
||||
今天的题目思路很简单,但是一遍 AC 也是不容易的。链表大部分题目考察的都是考生代码的完整性和鲁棒性,所以有些题目我们看着思路很简单,但是想直接通过还是需要下一翻工夫的,所以建议大家将所有链表的题目都自己写一下。实在没有时间做的同学,可以自己在脑子里打一遍代码,想清每一行代码的作用。
|
||||
|
||||
迭代法:
|
||||
|
||||
@@ -47,7 +47,7 @@ Java Code:
|
||||
l1 = l1.next;
|
||||
}
|
||||
headpro = headpro.next;
|
||||
}
|
||||
}
|
||||
headpro.next = l1 != null ? l1:l2;
|
||||
return headtemp.next;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
l1 = l1->next;
|
||||
}
|
||||
headpro = headpro->next;
|
||||
}
|
||||
}
|
||||
headpro->next = l1 != nullptr ? l1: l2;
|
||||
return headtemp->next;
|
||||
}
|
||||
@@ -83,23 +83,22 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var mergeTwoLists = function(l1, l2) {
|
||||
let headpro = new ListNode(-1);
|
||||
let headtemp = headpro;
|
||||
while (l1 && l2) {
|
||||
//接上大的那个
|
||||
if (l1.val >= l2.val) {
|
||||
headpro.next = l2;
|
||||
l2 = l2.next;
|
||||
}
|
||||
else {
|
||||
headpro.next = l1;
|
||||
l1 = l1.next;
|
||||
}
|
||||
headpro = headpro.next;
|
||||
}
|
||||
headpro.next = l1 != null ? l1:l2;
|
||||
return headtemp.next;
|
||||
var mergeTwoLists = function (l1, l2) {
|
||||
let headpro = new ListNode(-1);
|
||||
let headtemp = headpro;
|
||||
while (l1 && l2) {
|
||||
//接上大的那个
|
||||
if (l1.val >= l2.val) {
|
||||
headpro.next = l2;
|
||||
l2 = l2.next;
|
||||
} else {
|
||||
headpro.next = l1;
|
||||
l1 = l1.next;
|
||||
}
|
||||
headpro = headpro.next;
|
||||
}
|
||||
headpro.next = l1 != null ? l1 : l2;
|
||||
return headtemp.next;
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,14 +1,14 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [剑指 Offer 52. 两个链表的第一个公共节点](https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/) & [160. 相交链表](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/)
|
||||
|
||||
### 前言
|
||||
|
||||
今天给大家带来一个不是那么难的题目,这个题目的解答方法很多,只要能AC的就是好方法,虽然题目不是特别难但是也是剑指offer上的经典题目所以大家要记得打卡呀。
|
||||
今天给大家带来一个不是那么难的题目,这个题目的解答方法很多,只要能 AC 的就是好方法,虽然题目不是特别难但是也是剑指 offer 上的经典题目所以大家要记得打卡呀。
|
||||
|
||||
然后今天我们的链表板块就算结束啦。周末的时候我会对链表的题目做一个总结,俗话说温故而知新嘛。好啦废话不多说,我们一起来看一下今天的题目吧!
|
||||
|
||||
@@ -16,19 +16,13 @@
|
||||
|
||||
输入两个链表,找出它们的第一个公共节点。如下图,返回黄色结点即可。
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
题目表达是不是也很简单,这个题目我的方法一共有两个,一种就是用HashSet进行存储,一种就是利用双指针,大家有更好的可以在下面讨论呀。
|
||||
题目表达是不是也很简单,这个题目我的方法一共有两个,一种就是用 HashSet 进行存储,一种就是利用双指针,大家有更好的可以在下面讨论呀。
|
||||
|
||||
### HashSet
|
||||
|
||||
这个方法是比较简单的,主要思路就是,先遍历一个链表将链表的所有值都存到Hashset中,然后再遍历另一个链表,如果发现某个结点在Hashset中已经存在那我们直接返回该节点即可,代码也很简单。
|
||||
|
||||
|
||||
这个方法是比较简单的,主要思路就是,先遍历一个链表将链表的所有值都存到 Hashset 中,然后再遍历另一个链表,如果发现某个结点在 Hashset 中已经存在那我们直接返回该节点即可,代码也很简单。
|
||||
|
||||
**题目代码**
|
||||
|
||||
@@ -55,7 +49,7 @@ public class Solution {
|
||||
}
|
||||
//若上方没有返回,此刻tempb为null
|
||||
return tempb;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -91,25 +85,25 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var getIntersectionNode = function(headA, headB) {
|
||||
let tempa = headA;
|
||||
let tempb = headB;
|
||||
//定义Hashset
|
||||
let arr = new Set();
|
||||
//遍历链表A,将所有值都存到arr中
|
||||
while (tempa) {
|
||||
arr.add(tempa);
|
||||
tempa = tempa.next;
|
||||
var getIntersectionNode = function (headA, headB) {
|
||||
let tempa = headA;
|
||||
let tempb = headB;
|
||||
//定义Hashset
|
||||
let arr = new Set();
|
||||
//遍历链表A,将所有值都存到arr中
|
||||
while (tempa) {
|
||||
arr.add(tempa);
|
||||
tempa = tempa.next;
|
||||
}
|
||||
//遍历列表B,如果发现某个结点已在arr中则直接返回该节点
|
||||
while (tempb) {
|
||||
if (arr.has(tempb)) {
|
||||
return tempb;
|
||||
}
|
||||
//遍历列表B,如果发现某个结点已在arr中则直接返回该节点
|
||||
while (tempb) {
|
||||
if (arr.has(tempb)) {
|
||||
return tempb;
|
||||
}
|
||||
tempb = tempb.next;
|
||||
}
|
||||
//若上方没有返回,此刻tempb为null
|
||||
return tempb;
|
||||
tempb = tempb.next;
|
||||
}
|
||||
//若上方没有返回,此刻tempb为null
|
||||
return tempb;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -170,7 +164,6 @@ extension ListNode: Hashable, Equatable {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
下面这个方法比较巧妙,不是特别容易想到,大家可以自己实现一下,这个方法也是利用我们的双指针思想。
|
||||
|
||||
下面我们直接看动图吧,特别直观,一下就可以搞懂。
|
||||
@@ -179,8 +172,6 @@ extension ListNode: Hashable, Equatable {
|
||||
|
||||
是不是一下就懂了呀,我们利用双指针,当某一指针遍历完链表之后,然后掉头去另一个链表的头部,继续遍历。因为速度相同所以他们第二次遍历的时候肯定会相遇,是不是很浪漫啊!
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
@@ -225,17 +216,17 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var getIntersectionNode = function(headA, headB) {
|
||||
//定义两个节点
|
||||
let tempa = headA;
|
||||
let tempb = headB;
|
||||
//循环
|
||||
while (tempa != tempb) {
|
||||
//如果不为空就指针下移,为空就跳到另一链表的头部
|
||||
tempa = tempa != null ? tempa.next: headB;
|
||||
tempb = tempb != null ? tempb.next: headA;
|
||||
}
|
||||
return tempa;//返回tempb也行
|
||||
var getIntersectionNode = function (headA, headB) {
|
||||
//定义两个节点
|
||||
let tempa = headA;
|
||||
let tempb = headB;
|
||||
//循环
|
||||
while (tempa != tempb) {
|
||||
//如果不为空就指针下移,为空就跳到另一链表的头部
|
||||
tempa = tempa != null ? tempa.next : headB;
|
||||
tempb = tempb != null ? tempb.next : headA;
|
||||
}
|
||||
return tempa; //返回tempb也行
|
||||
};
|
||||
```
|
||||
|
||||
@@ -282,12 +273,5 @@ class Solution {
|
||||
>
|
||||
> 在这里带大家来看看一些其他的解题方法,虽然没有双指针有效,但还是值得一试。
|
||||
>
|
||||
> 1. 两个链表各遍历一次,找出长度。根据长度差k,让较长的那个链表先走k步。之后再两个指针一起走,由于起点一样,两个指针必将一起到达公共节点。
|
||||
> 1. 两个链表各遍历一次,找出长度。根据长度差 k,让较长的那个链表先走 k 步。之后再两个指针一起走,由于起点一样,两个指针必将一起到达公共节点。
|
||||
> 2. 将其中一条链表的头和尾相连,公共节点就是环的入口,直接套用之前学过的算法就可以啦。(这解法看得我拍腿叫好)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,14 +1,14 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [剑指 Offer 22. 链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/)
|
||||
#### [剑指 Offer 22. 链表中倒数第 k 个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/)
|
||||
|
||||
题目:
|
||||
|
||||
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
|
||||
输入一个链表,输出该链表中倒数第 k 个节点。为了符合大多数人的习惯,本题从 1 开始计数,即链表的尾节点是倒数第 1 个节点。例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
|
||||
|
||||
题目分析:
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
我们遇到这个题目,可能会有什么答题思路呢?
|
||||
|
||||
你看我说的对不对,是不是会想到先遍历一遍链表知道 链表节点的个数,然后再计算出倒数第n个节点。
|
||||
你看我说的对不对,是不是会想到先遍历一遍链表知道 链表节点的个数,然后再计算出倒数第 n 个节点。
|
||||
|
||||
比如链表长度为10,倒数第3个节点,不就是正数第8个节点呀,这种方法当然可以啦,是可以实现的,那么我们再思考一下有没有其他方法呢?哦,对,我们可以将链表元素保存到数组里面,然后直接就可以知道倒数第k个节点了。这个方法确实比刚才那个方法省时间了,但是所耗的空间更多了,那我们还有什么方法吗?
|
||||
比如链表长度为 10,倒数第 3 个节点,不就是正数第 8 个节点呀,这种方法当然可以啦,是可以实现的,那么我们再思考一下有没有其他方法呢?哦,对,我们可以将链表元素保存到数组里面,然后直接就可以知道倒数第 k 个节点了。这个方法确实比刚才那个方法省时间了,但是所耗的空间更多了,那我们还有什么方法吗?
|
||||
|
||||
我们可以继续利用我们的双指针呀,但是我们应该怎么做呢?
|
||||
|
||||
双指针法:
|
||||
|
||||
首先一个指针移动K-1位(这里可以根据你的初始化指针决定),然后另一个指针开始启动,他俩移动速度一样,所以他俩始终相差K-1位,当第一个指针到达链表尾部时,第二个指针的指向则为倒数第K个节点。
|
||||
首先一个指针移动 K-1 位(这里可以根据你的初始化指针决定),然后另一个指针开始启动,他俩移动速度一样,所以他俩始终相差 K-1 位,当第一个指针到达链表尾部时,第二个指针的指向则为倒数第 K 个节点。
|
||||
|
||||

|
||||
|
||||
@@ -50,7 +50,7 @@ class Solution {
|
||||
//先移动绿指针到指定位置
|
||||
for (int i = 0; i < k-1; i++) {
|
||||
pro = pro.next;
|
||||
}
|
||||
}
|
||||
//两个指针同时移动
|
||||
while (pro.next != null) {
|
||||
pro = pro.next;
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
//先移动绿指针到指定位置
|
||||
for (int i = 0; i < k-1; i++) {
|
||||
pro = pro->next;
|
||||
}
|
||||
}
|
||||
//两个指针同时移动
|
||||
while (pro->next != nullptr) {
|
||||
pro = pro->next;
|
||||
@@ -94,23 +94,25 @@ public:
|
||||
```
|
||||
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var getKthFromEnd = function(head, k) {
|
||||
//特殊情况
|
||||
if(!head) return head;
|
||||
//初始化两个指针, 定义指针指向
|
||||
let pro = head, after = head;
|
||||
//先移动绿指针到指定位置
|
||||
for(let i = 0; i < k - 1; i++){
|
||||
pro = pro.next;
|
||||
}
|
||||
//两个指针同时移动
|
||||
while(pro.next){
|
||||
pro = pro.next;
|
||||
after = after.next;
|
||||
}
|
||||
//返回倒数第k个节点
|
||||
return after;
|
||||
var getKthFromEnd = function (head, k) {
|
||||
//特殊情况
|
||||
if (!head) return head;
|
||||
//初始化两个指针, 定义指针指向
|
||||
let pro = head,
|
||||
after = head;
|
||||
//先移动绿指针到指定位置
|
||||
for (let i = 0; i < k - 1; i++) {
|
||||
pro = pro.next;
|
||||
}
|
||||
//两个指针同时移动
|
||||
while (pro.next) {
|
||||
pro = pro.next;
|
||||
after = after.next;
|
||||
}
|
||||
//返回倒数第k个节点
|
||||
return after;
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,14 +1,14 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [876. 链表的中间结点](https://leetcode-cn.com/problems/middle-of-the-linked-list/)
|
||||
|
||||
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
|
||||
|
||||
如果有两个中间结点,则返回第二个中间结点。
|
||||
如果有两个中间结点,则返回第二个中间结点。
|
||||
|
||||
**示例 1:**
|
||||
|
||||
@@ -32,13 +32,13 @@
|
||||
|
||||
又精心筛选了一个题目,本来想写一下删除节点的题目,然后发现这个题目更符合目前的节奏,所以先写一下这个题目,明天再给大家写删除节点的题目。
|
||||
|
||||
大家先不要看我的题解,先自己想一下怎么做。这个这个题目是想让我们找出中间节点,昨天的题目是让我们倒数第K个节点,想一下这两个题目有什么联系呢?
|
||||
大家先不要看我的题解,先自己想一下怎么做。这个这个题目是想让我们找出中间节点,昨天的题目是让我们倒数第 K 个节点,想一下这两个题目有什么联系呢?
|
||||
|
||||
先说一下刚开始刷题的小伙伴可能会想到的题解,两次遍历链表,第一次遍历获取链表长度,第二次遍历获取中间链表。
|
||||
|
||||
这个方法很OK,利用数组先将所有链表元素存入数组里,然后再直接获得中间节点。这个也很OK,那么我们有没有一次遍历,且不开辟辅助空间的方法呢?
|
||||
这个方法很 OK,利用数组先将所有链表元素存入数组里,然后再直接获得中间节点。这个也很 OK,那么我们有没有一次遍历,且不开辟辅助空间的方法呢?
|
||||
|
||||
昨天的题目是一前一后双指针,两个指针之间始终相差k-1位,我们今天也利用一下双指针的做法吧。
|
||||
昨天的题目是一前一后双指针,两个指针之间始终相差 k-1 位,我们今天也利用一下双指针的做法吧。
|
||||
|
||||
这种类型的双指针是我们做链表的题目经常用到的,叫做快慢指针。
|
||||
|
||||
@@ -63,7 +63,7 @@ class Solution {
|
||||
slow = slow.next;
|
||||
}
|
||||
//返回slow指针指向的节点
|
||||
return slow;
|
||||
return slow;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
slow = slow->next;
|
||||
}
|
||||
//返回slow指针指向的节点
|
||||
return slow;
|
||||
return slow;
|
||||
}
|
||||
};
|
||||
```
|
||||
@@ -90,16 +90,16 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var middleNode = function(head) {
|
||||
let fast = head;//快指针
|
||||
let slow = head;//慢指针
|
||||
//循环条件,思考一下跳出循环的情况
|
||||
while (fast && fast.next) {
|
||||
fast = fast.next.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
//返回slow指针指向的节点
|
||||
return slow
|
||||
var middleNode = function (head) {
|
||||
let fast = head; //快指针
|
||||
let slow = head; //慢指针
|
||||
//循环条件,思考一下跳出循环的情况
|
||||
while (fast && fast.next) {
|
||||
fast = fast.next.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
//返回slow指针指向的节点
|
||||
return slow;
|
||||
};
|
||||
```
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[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 + 题目 + 问题 向我反馈
|
||||
>
|
||||
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
|
||||
>
|
||||
> 另外希望手机阅读的同学可以来我的 <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>进入。
|
||||
|
||||
#### [面试题 02.05. 链表求和](https://leetcode-cn.com/problems/sum-lists-lcci/)
|
||||
|
||||
之前我们一起做了链表中的几个经典题型,找到倒数第k个节点,找链表中点,判断链表中环的起点,合并链表,反转链表,删除链表中重复值。这些是链表中的经典问题,面试中也经常会考的问题,然后下面我们继续做一道链表题目,也是面试中经常会考的题目,链表求和问题。
|
||||
之前我们一起做了链表中的几个经典题型,找到倒数第 k 个节点,找链表中点,判断链表中环的起点,合并链表,反转链表,删除链表中重复值。这些是链表中的经典问题,面试中也经常会考的问题,然后下面我们继续做一道链表题目,也是面试中经常会考的题目,链表求和问题。
|
||||
|
||||
另外有一些小伙伴说,虽然一天一道题不算多,但是每天读题,做题加消化稍微有点跟不上,所以我打算每个周的工作日进行更新题目,到周末的时候对本周的题目进行总结,然后为大家再写一些别的东西。下面我们一起来看一下今天的题目吧。
|
||||
|
||||
@@ -18,23 +18,23 @@
|
||||
|
||||
这些数位是反向存放的,也就是个位排在链表首部。
|
||||
|
||||
编写函数对这两个整数求和,并用链表形式返回结果。
|
||||
编写函数对这两个整数求和,并用链表形式返回结果。
|
||||
|
||||
示例1:
|
||||
示例 1:
|
||||
|
||||
```java
|
||||
输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即 617 + 295
|
||||
输出:2 -> 1 -> 9,即 912
|
||||
```
|
||||
|
||||
示例2:
|
||||
示例 2:
|
||||
|
||||
```java
|
||||
输入:(9 -> 9) + (9 -> 9),即 99 + 99
|
||||
输出:8 -> 9 -> 1
|
||||
```
|
||||
|
||||
示例3:
|
||||
示例 3:
|
||||
|
||||
```java
|
||||
输入:(5) + (5),即 5 + 5
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
我们应该对链表的每一位进行相加,然后通过链表的和,判断是否需要像下一位进行传递,
|
||||
|
||||
就好比小时候我们用竖式进行加法一样,判断两位相加是否大于10,大于10则进1。
|
||||
就好比小时候我们用竖式进行加法一样,判断两位相加是否大于 10,大于 10 则进 1。
|
||||
|
||||
了解了思路,但是想完全实现代码也不是特别容易,这里需要注意的三个点就是,
|
||||
|
||||
@@ -59,17 +59,15 @@
|
||||
|
||||
2. 需要创建一个变量用来保存进位值。
|
||||
|
||||
3. 当跳出循环之后,需要根据进位值来判断需不需要再对链表长度加1。
|
||||
3. 当跳出循环之后,需要根据进位值来判断需不需要再对链表长度加 1。
|
||||
|
||||
这三条可以结合代码理解进行。
|
||||
|
||||
注:进位值只能是0或1,因为每一位最大为9,9+9=18;
|
||||
注:进位值只能是 0 或 1,因为每一位最大为 9,9+9=18;
|
||||
|
||||

|
||||
|
||||
注:这里需要注意得时,链表遍历结束,我们应该跳出循环,但是我们的 nlist 仍在尾部添加了1节点,那是因为跳出循环时,summod 值为1,所以我们需要在尾部再添加一个节点。
|
||||
|
||||
|
||||
注:这里需要注意得时,链表遍历结束,我们应该跳出循环,但是我们的 nlist 仍在尾部添加了 1 节点,那是因为跳出循环时,summod 值为 1,所以我们需要在尾部再添加一个节点。
|
||||
|
||||
**题目代码**
|
||||
|
||||
@@ -93,7 +91,7 @@ class Solution {
|
||||
//更新进位值,例18/10=1,9/10=0
|
||||
summod = sum/10;
|
||||
//新节点保存的值,18%8=2,则添加2
|
||||
sum = sum%10;
|
||||
sum = sum%10;
|
||||
//添加节点
|
||||
tempnode.next = new ListNode(sum);
|
||||
//移动指针
|
||||
@@ -103,7 +101,7 @@ class Solution {
|
||||
}
|
||||
if (l2 != null) {
|
||||
l2 = l2.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
//最后根据进位值判断需不需要继续添加节点
|
||||
if (summod != 0) {
|
||||
@@ -135,7 +133,7 @@ public:
|
||||
//更新进位值,例18/10=1,9/10=0
|
||||
summod = sum / 10;
|
||||
//新节点保存的值,18%8=2,则添加2
|
||||
sum = sum % 10;
|
||||
sum = sum % 10;
|
||||
//添加节点
|
||||
tempnode->next = new ListNode(sum);
|
||||
//移动指针
|
||||
@@ -145,7 +143,7 @@ public:
|
||||
}
|
||||
if (l2 != nullptr) {
|
||||
l2 = l2->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
//最后根据进位值判断需不需要继续添加节点
|
||||
if (summod != 0) {
|
||||
@@ -159,39 +157,39 @@ public:
|
||||
JS Code:
|
||||
|
||||
```js
|
||||
var addTwoNumbers = function(l1, l2) {
|
||||
//待会儿要返回的链表
|
||||
let nList = new ListNode(-1);//哑节点
|
||||
let tempnode = nList;
|
||||
//用来保存进位值,初始化为0
|
||||
let summod = 0;
|
||||
while (l1 || l2) {
|
||||
//如果l1的链表为空则l1num为0,若是不为空,则为链表的节点值
|
||||
//判断是否为空,为空就设为0
|
||||
let l1num = l1 === null ? 0 : l1.val;
|
||||
let l2num = l2 === null ? 0 : l2.val;
|
||||
//将链表的值和进位值相加,得到为返回链表的值
|
||||
let sum = l1num + l2num + summod;
|
||||
//更新进位值,例18/10=1,9/10=0
|
||||
summod = ~~(sum / 10);
|
||||
//新节点保存的值,18%8=2,则添加2
|
||||
sum = sum % 10;
|
||||
//添加节点
|
||||
tempnode.next = new ListNode(sum);
|
||||
//移动指针
|
||||
tempnode = tempnode.next;
|
||||
if (l1) {
|
||||
l1 = l1.next;
|
||||
}
|
||||
if (l2) {
|
||||
l2 = l2.next;
|
||||
}
|
||||
var addTwoNumbers = function (l1, l2) {
|
||||
//待会儿要返回的链表
|
||||
let nList = new ListNode(-1); //哑节点
|
||||
let tempnode = nList;
|
||||
//用来保存进位值,初始化为0
|
||||
let summod = 0;
|
||||
while (l1 || l2) {
|
||||
//如果l1的链表为空则l1num为0,若是不为空,则为链表的节点值
|
||||
//判断是否为空,为空就设为0
|
||||
let l1num = l1 === null ? 0 : l1.val;
|
||||
let l2num = l2 === null ? 0 : l2.val;
|
||||
//将链表的值和进位值相加,得到为返回链表的值
|
||||
let sum = l1num + l2num + summod;
|
||||
//更新进位值,例18/10=1,9/10=0
|
||||
summod = ~~(sum / 10);
|
||||
//新节点保存的值,18%8=2,则添加2
|
||||
sum = sum % 10;
|
||||
//添加节点
|
||||
tempnode.next = new ListNode(sum);
|
||||
//移动指针
|
||||
tempnode = tempnode.next;
|
||||
if (l1) {
|
||||
l1 = l1.next;
|
||||
}
|
||||
//最后根据进位值判断需不需要继续添加节点
|
||||
if (summod !== 0) {
|
||||
tempnode.next = new ListNode(summod);
|
||||
if (l2) {
|
||||
l2 = l2.next;
|
||||
}
|
||||
return nList.next;//去除哑节点
|
||||
}
|
||||
//最后根据进位值判断需不需要继续添加节点
|
||||
if (summod !== 0) {
|
||||
tempnode.next = new ListNode(summod);
|
||||
}
|
||||
return nList.next; //去除哑节点
|
||||
};
|
||||
```
|
||||
|
||||
@@ -239,11 +237,11 @@ class Solution {
|
||||
var nList = ListNode(-1) // 哑节点
|
||||
var tempnode = nList
|
||||
// 用来保存进位值,初始化为0
|
||||
var summod = 0
|
||||
var summod = 0
|
||||
while l1 != nil || l2 != nil {
|
||||
// 链表的节点值
|
||||
let l1num = l1?.val ?? 0
|
||||
let l2num = l2?.val ?? 0
|
||||
let l1num = l1?.val ?? 0
|
||||
let l2num = l2?.val ?? 0
|
||||
// 将链表的值和进位值相加,得到为返回链表的值
|
||||
var sum = l1num + l2num + summod
|
||||
// 更新进位值,例18/10=1,9/10=0
|
||||
|
Reference in New Issue
Block a user