题目
给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点。
示例 1:
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
示例 2:
输入: head = [1,2]
输出: [2,1]
示例 3:
输入: head = []
输出: []
提示:
- 链表中节点的数目范围是
[0, 5000] -5000 <= Node.val <= 5000
题解
本题可以使用递归的解法, 链表天然递归的性质,反转链表可以拆分为两个子问题:
- 反转头结点
- 反转头结点后剩下的子节点
而子问题2求解方式和反转链表一样, 反转头结点后剩下的子节点 又可以拆分为反转头结点 和 反转头结点后剩下的子节点,依次类推,直到链表只剩下一个节点,
存在的最小子问题是只有一个节点,可以不用反转, 直接返回。
示例 1:
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
示例1的具体执行流程:
首先链表递归,执行递的过程,递到尾结点, 然后再从尾节点一层一层向上归,完成反转链表
// 递的过程
1 -> 2 -> 3 -> 4 -> 5 -> null
2 -> 3 -> 4 -> 5 -> null
3 -> 4 -> 5 -> null
4 -> 5 -> null
5 -> null
// 归的过程
// 有两个节点,当前head = 2, 把head.next.next = head, head.next = null
// 即 5-> 4 -> 3 -> 2 -> 1
null <- 1 <- 2 <- 3 <- 4 <- 5
// 有两个节点,当前head = 2, 把head.next.next = head, head.next = null
// 即 5-> 4 -> 3 -> 2
2 <- 3 <- 4 <- 5
// 有两个节点,当前head = 3, 把head.next.next = head, head.next = null
// 即 5-> 4 -> 3
3 <- 4 <- 5
// 有两个节点,当前head = 3, 把head.next.next = head, head.next = null
// 即 5-> 4
4 <- 5
//只有一个节点不反转
5 -> null
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
if (head == null || head.next == null) {
return head;
}
let newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
};