leetcode:206. 反转链表
解题思路:
[1,2,3,4,5]
reverse(head.next)
执行完成后,整个链表就成了这样:1-> 2<-3<-4<-5- 此时2指向了null
- 要让1指向null,2指向1,所以 head.next.next = head; head.next=null
- 当链表递归反转之后,新的头结点是
last
var reverseList = function(head) {
if (!head || !head.next) return head
let last = reverseList(head.next)
head.next.next = head
head.next = null
return last
};
//迭代写法:
var reverseList = function(head) {
if (!head || !head.next) return head
let newHead = null
while (head) {
let temp = head.next
head.next = newHead
newHead = head
head = temp
}
return newHead
};
反转链表前 N 个节点
解题思路:
[1,2,3,4,5] n=31、
n == 1
,反转一个元素,就是它本身,同时要记录后驱节点。2、
head
节点在递归反转之后不一定是最后一个节点了,所以要记录后驱p
(第n + 1
个节点),反转之后将head
连接上。
let p = null // 后驱节点
var revereseN = function (head, n) {
if (n == 1) {
p = head.next //第n+1个节点
return head
}
let last = revereseN(head.next, n - 1) //以head.next为起点,需要反转前n-1个节点
head.next.next = head
head.next = p // 让反转之后的 head 节点和后面的节点连起来
return last
}
leetcode:92. 反转链表 II
解题思路:
- 如果
left == 1
,就相当于反转链表开头的n
个元素嘛,即上面代码实现的功能- 如果
left != 1
,把head
的索引视为 1,那么就是从第left翻天
个元素开始反转;如果把head.next
的索引视为 1 ,反转的区间应该是从第left - 1
个元素开始的
let p = null // 后驱节点
var revereseN = function (head, n) {
if (n == 1) {
p = head.next //第n+1个节点
return head
}
let last = revereseN(head.next, n - 1) //以head.next为起点,需要反转前n-1个节点
head.next.next = head
head.next = p // 让反转之后的 head 节点和后面的节点连起来
return last
}
var reverseBetween = function (head, left, right) {
if (left == 1) {
return revereseN(head, right)
}
head.next = reverseBetween(head.next, left - 1, right - 1)
return head
};
leetcode:25. K 个一组翻转链表
1、给定链表头结点,反转整个链表
// 反转以 a 为头结点的链表 : 其实就是「反转 a 到 null 之间的结点」
var reverser = function (a) {
let pre = null,
cur = a,
nxt = a
while (cur) {
nxt = cur.next
// 逐个结点反转
cur.next = pre
pre = cur
cur = nxt
}
return pre // 返回反转后的头结点
}
2、反转 a
到 b
之间的结点
/** 反转区间 [a, b) 的元素-左闭右开 */
var reverser = function (a, b) {
let pre = null,
cur = a,
nxt = a
while (cur != b) { //修改这里的终止条件
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
}
return pre
}
3、实现K个一组翻转链表
var reverser = function (a, b) {
let pre = null,
cur = a,
nxt = a
while (cur != b) {
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
}
return pre
}
var reverseKGroup = function (head, k) {
if (!head) return null
let a = b = head
for (let i = 0; i < k; i++) {
if (!b) return head //没有K个,就不反转
b = b.next //走到b的区间
}
let newHead = reverser(a, b) //反转前K个
a.next = reverseKGroup(b, k) //递归后链表连接起来
return newHead
};