「时光不负,创作不停,本文正在参加2021年终总结征文大赛」
leetcode 反转链表
描述: 1 -> 2 -> 3 -> 4 -> 5 变成 5 -> 4 -> 3 -> 2 -> 1
思路:
- 当前指针是1的时候, 需要next 指向 null, 当前指针是 2 的时候 需要 next 指向前面已经反转的 1 -> null, 依次遍历单前指针指向下个节点 直到到尾结点
- 但是链表是空或者一个节点的时候反转还是本身
循环
function reverseList(head) {
// 先判断是空或者一个节点
if (head === null || head.next === null) return head
// 记录当前指针
let cur = head
// 记录已经反转的链表,初始值是个空
let prev = null
// 记录下个节点
let p = head.next
// 逐个遍历
while(cur) {
// 当前指针的下个节点指向已经反转的链表
cur.next = prev
// 更新已反转的链表
prev = cur
// 需要遍历,变动当前指针, 变成下个节点
cur = p
// 然后变化下个节点 直到尾结点
if(p) p = p.next
}
// 把反转的链表return
return prev
}
递归
思路:
1. 1 -> 2 三个链表的时候, 我们需要怎么反转
let head = {
val: 1,
next: {
val: 2,
next: null
}
}
const tail = head.next
tail.next = head
head.next = null
// tail 就是我们的值 代表已反转的值
let head = {
val: 1,
next: {
val: 2,
next: {
val: 3,
next: null
}
}
}
const tail = head.next
const p = tail.next
head.next = null
tail.next = head
p.next = tail
// p代表反转的值 tail 相当于val:3 之前反转的值
则
function reverseList(head) {
// 空或一个节点
if(head === null || head.next === null) return head
// 用tail 记录已经反转的节点
let tail = head.next
// 然后反转剩余节点 用p记录
let p = reverseList(tail)
// 反转第一个和第二个节点
head.next = tail.next // 第一个节点的next 指向 tail.next
tail.next = head // tail的next 指向head
return p
}
总结
- 反转链表 - 当前节点的变动和next指针指向的变动
- 循环遍历可以用tmp保存cur.next的节点 不用记录p