题目描述
反转从位置 m
到 n
的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
解题思路
方法一:迭代+直接
- 分清楚四个边界,m - n 之间的链表直接反转
- 加上一个虚拟节点处理 m = 1 时的特殊情况
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} left
* @param {number} right
* @return {ListNode}
*/
var reverseBetween = function (head, m, n) {
if (!head) {
return null;
}
let cur = head;
let pre = null;
while (m > 1) {
pre = cur;
cur = cur.next;
m--;
n--;
}
// con 记录的是 m的前一个节点
// tail 记录的是 n 的位置
let con = pre;
let tail = cur;
// 反转链表的套路
while (n > 0) {
let next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
n--;
}
// 当 m = 1 时,会出现边界的问题
if (con !== null) {
con.next = pre;
} else {
head = pre;
}
tail.next = cur;
return head;
};
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} m
* @param {number} n
* @return {ListNode}
*/
// todo 优化版
var reverseBetween = function (head, m, n) {
let count = n - m;
let p = (dummyHead = new ListNode());
let pre, cur, tail, front;
p.next = head;
for (let i = 0; i < m - 1; i++) {
p = p.next;
}
front = p;
pre = tail = p.next;
cur = pre.next;
for (let i = 0; i < count; i++) {
let next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
front.next = pre;
tail.next = cur;
return dummyHead.next;
};