解法一: 递归
思路: 假设要反转的列表为[1,2,3,4,5],利用递归回溯法,走到倒数第二节点时,此时递归走到了第节点为4处,,利用当前节点或者当前节点的下一个节点不为空拿到反转后的头节点(5的下一个节点为空,所以5就是头节点)
if (head === null || head.next === null) {
return head
}
let curNode = reverseList(head.next)
console.log('反转前', head, curNode)
// 输出 [4, 5] [5]
执行反转,并打印结果
head.next.next = head
head.next = null
console.log('反转后', head, curNode)
// 输出 [4], [5, 4]
以此类推结果分别是
反转前 [4,5] [5]
反转后 [4] [5,4]
反转前 [3,4] [5,4]
反转后 [3] [5,4,3]
反转前 [2,3] [5,4,3]
反转后 [2] [5,4,3,2]
反转前 [1,2] [5,4,3,2]
反转后 [1] [5,4,3,2,1]
最后返回curNode, 完整代码为
var reverseList = function(head) {
if (head === null || head.next === null) {
return head
}
let curNode = reverseList(head.next)
console.log('反转前', head, curNode)
head.next.next = head
head.next = null
console.log('反转后', head, curNode)
return curNode
};
解法二: 迭代法
思路: 每次迭代前记录前一个节点preNode, 和后一个节点next, 让当前节点的下一个节点指向前一个节点,然后当前节点向后移动,重复执行此操作,知道最后一个节点,前一个节点各次迭代的结果就是
null
null <- 1
null <- 1 <- 2
null <- 1 <- 2 <- 3
...
// 实现步骤,最后preNode指向最后一个节点,输出为 [..., 3, 2, 1]
最后输出preNode
var reverseList = function(head) {
let preNode = null
let cur = head
while(cur) {
let next = cur.next
cur.next = preNode
preNode = cur
cur = next
}
return preNode
};