Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fdccb77

Browse files
author
zhangxing
committed
chore: 链表
1 parent 1a55ce4 commit fdccb77

File tree

2 files changed

+262
-0
lines changed

2 files changed

+262
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L2doL2Nob2NvbGF0ZTE5OTkvY2RuL2ltZy8yMDIwMDgyODE0NTUyMS5qcGc?x-oss-process=image/format,png)
2+
3+
> 仰望星空的人,不应该被嘲笑
4+
5+
## 题目描述
6+
7+
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
8+
9+
说明:
10+
1 ≤ m ≤ n ≤ 链表长度。
11+
12+
示例:
13+
14+
```javascript
15+
输入: 1->2->3->4->5->NULL, m = 2, n = 4
16+
输出: 1->4->3->2->5->NULL
17+
```
18+
19+
来源:力扣(LeetCode)
20+
链接:https://leetcode-cn.com/problems/reverse-linked-list-ii
21+
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
22+
23+
## 解题思路
24+
25+
**借助递归**
26+
27+
```javascript
28+
/**
29+
* Definition for singly-linked list.
30+
* function ListNode(val) {
31+
* this.val = val;
32+
* this.next = null;
33+
* }
34+
*/
35+
/**
36+
* @param {ListNode} head
37+
* @param {number} m
38+
* @param {number} n
39+
* @return {ListNode}
40+
*/
41+
var reverseBetween = function (head, m, n) {
42+
let reverse = (pre, cur) => {
43+
if (!cur) return pre; // 返回的就是原链表的尾结点也就是新链表的头结点
44+
let tmp = cur.next;
45+
cur.next = pre;
46+
return reverse(cur, tmp);
47+
};
48+
let dummyHead = new ListNode();
49+
dummyHead.next = head;
50+
let p = dummyHead;
51+
let k = m - 1;
52+
// 先找到需要反转链表部分的前驱节点
53+
while (k--) {
54+
p = p.next;
55+
}
56+
// 保存前驱节点
57+
let front = p;
58+
// 找到需要反转链表部分的头节点
59+
let frontNode = front.next;
60+
k = n - m + 1;
61+
// 再找到需要反转链表部分的尾节点
62+
while (k--) {
63+
p = p.next;
64+
}
65+
// 找到需要反转链表部分的尾节点
66+
let endNode = p;
67+
// 保存后继节点
68+
let end = endNode.next;
69+
// 将后继值为空,开始反转链表
70+
// 构造出一个"新的链表"(链表的最后一个节点的next为null)
71+
endNode.next = null;
72+
// reverse 返回的就是"新链表"反转之后的头结点
73+
front.next = reverse(null, frontNode);
74+
// 原本的反转链表部分的头节点现在变成了尾节点,指向原本的后继节点
75+
frontNode.next = end;
76+
return dummyHead.next;
77+
};
78+
```
79+
80+
**迭代解法**
81+
82+
```javascript
83+
/**
84+
* Definition for singly-linked list.
85+
* function ListNode(val) {
86+
* this.val = val;
87+
* this.next = null;
88+
* }
89+
*/
90+
/**
91+
* @param {ListNode} head
92+
* @param {number} m
93+
* @param {number} n
94+
* @return {ListNode}
95+
*/
96+
var reverseBetween = function (head, m, n) {
97+
let dummyHead = new ListNode();
98+
dummyHead.next = head;
99+
let p = dummyHead;
100+
let k = m - 1;
101+
// 先找到需要反转链表部分的前驱节点
102+
while (k--) {
103+
p = p.next;
104+
}
105+
// 保存前驱节点
106+
let front = p;
107+
let pre = (frontNode = front.next);
108+
let cur = pre.next;
109+
k = n - m;
110+
// 长度为3的链表需要反转2次,那么长度为n的链表需要反转n-1次
111+
while (k--) {
112+
let tmp = cur.next;
113+
cur.next = pre;
114+
pre = cur;
115+
cur = tmp;
116+
}
117+
// 将原本前驱节点的next指向当前反转后的链表
118+
front.next = pre;
119+
// 原本反转链表的头节点现在变成了尾结点,指向后继节点
120+
frontNode.next = cur;
121+
return dummyHead.next;
122+
};
123+
```
124+
125+
## 最后
126+
127+
文章产出不易,还望各位小伙伴们支持一波!
128+
129+
往期精选:
130+
131+
<a href="https://github.com/Chocolate1999/Front-end-learning-to-organize-notes">小狮子前端の笔记仓库</a>
132+
133+
<a href="https://github.com/Chocolate1999/leetcode-javascript">leetcode-javascript:LeetCode 力扣的 JavaScript 解题仓库,前端刷题路线(思维导图)</a>
134+
135+
小伙伴们可以在 Issues 中提交自己的解题代码,🤝 欢迎 Contributing,可打卡刷题,Give a ⭐️ if this project helped you!
136+
137+
<a href="https://yangchaoyi.vip/">访问超逸の博客</a>,方便小伙伴阅读玩耍~
138+
139+
![](https://img-blog.csdnimg.cn/2020090211491121.png#pic_center)
140+
141+
```javascript
142+
学如逆水行舟,不进则退
143+
```
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/**
2+
* 节点的类
3+
*/
4+
class ListNode {
5+
/**
6+
*
7+
* @param {*} data 此结点存放的数据
8+
* @param {*} next 此结点下一个结点的引用地址
9+
*/
10+
constructor(data, next) {
11+
this.data = data;
12+
this.next = next;
13+
}
14+
}
15+
class List {
16+
constructor() {
17+
//第一个元素的引用地址 它向链表中的第一个元素
18+
this.head = null;
19+
//链表的长度 里面有几个元素
20+
this.size = 0;
21+
}
22+
/**
23+
* 在索引为index的位置 添加一个节点
24+
* @param {*} index
25+
* @param {*} listNode
26+
*/
27+
add(index, listNode) {
28+
//判断是否要添加到索引为0的位置
29+
//如果index=0.添加到头的位置
30+
if (index == 0) {
31+
//让新的节点的next指向原来的头节点
32+
listNode.next = this.head;
33+
//头结点指向这个添加的节点
34+
this.head = listNode;
35+
} else {
36+
//获取 要插入位置 节点的前一个节点 A
37+
let prev = this.get(index - 1);
38+
//让待插入的节点的next指向前一个节点的后一个节点
39+
//c.next=B B=a.next
40+
listNode.next = prev.next;
41+
//让上一个节点的next指向待插入的节点
42+
prev.next = listNode;
43+
}
44+
this.size++;
45+
}
46+
rangeCheck(index) {
47+
if (index < 0 || index >= this.size) {
48+
throw new Error('索引越界');
49+
}
50+
}
51+
/**
52+
* 获取指定索引的元素结点
53+
* @param {*} index
54+
*/
55+
get(index) {
56+
this.rangeCheck(index);
57+
//curr先指向头节点,也就是第一个元素
58+
//index=0,index=1
59+
let curr = this.head;
60+
while (index--) {
61+
curr = curr.next;
62+
}
63+
return curr;
64+
}
65+
remove(index) {
66+
if (index === 0) {
67+
this.head = this.head.next;
68+
} else {
69+
//获取待删除节点的前一个节点
70+
let prev = this.get(index - 1);
71+
//让prev也就是A节点的next指向待删除节点的.next
72+
prev.next = prev.next.next;
73+
}
74+
this.size--;
75+
}
76+
print() {
77+
let curr = this.head;
78+
let str = '';
79+
while (curr) {
80+
str += curr.data + '=>';
81+
curr = curr.next;
82+
}
83+
str += 'null';
84+
console.log(str);
85+
}
86+
}
87+
// //创建一个链表实例
88+
// let list = new List();
89+
// //创建一个结点A,数据域存的A,指针域为null
90+
// let a = new ListNode('A');
91+
// //把a节点添加到链表中
92+
// list.add(0, a);
93+
// //创建一个C节点
94+
// let c = new ListNode('C');
95+
// //把这个C节点添加到索引为1的位置
96+
// list.add(1, c);
97+
// let b = new ListNode('B');
98+
// //把这个C节点添加到索引为1的位置
99+
// list.add(1, b);
100+
// //删除索引为1的元素
101+
// list.remove(1);
102+
// let d = new ListNode('D');
103+
// list.add(0, d);
104+
// list.print();
105+
106+
function makeList(arr) {
107+
let list = new List();
108+
for (let i = 0; i < arr.length; i++) {
109+
let node = new ListNode(arr[i]);
110+
list.add(i, node);
111+
}
112+
list.print();
113+
return list;
114+
}
115+
116+
module.exports = {
117+
ListNode,
118+
makeList
119+
};

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /