题目
题目链接:leetcode-cn.com/leetbook/re…
题解
考研数据结构中也会出现的题~
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
* @return {ListNode}
*/
var reverseList = function(head) {
let vhead = new ListNode(null,null);
let temp;
while(head !== null) {
temp = vhead.next;
vhead.next = head;
head = head.next;
vhead.next.next = temp;
}
return vhead.next;
};
2、递归实现
题目提示中又说了可以使用递归实现,我之前用 C 语言写链表的题目的时候没有想到链表和递归有这么深厚的友谊,决定分析一下和查查资料,看看链表和递归的情谊为和浓于水;
首先我们知道递归主要由 递归体 和 递归结束条件 组成,对于求解某个问题时可以将整个大问题变成一个一个逻辑相同的子问题,那么这个问题就可能可以使用递归解决(汉诺塔问题是经典的可以使用递归实现的问题);
链表的结构是由一个一个的节点组成的,每个节点都是一样的结构,所以有关链表的问题其天然适于使用递归实现;
/**
* 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 rhead = reverseList(head.next); // 递归返回的时反转后的链表的第一个节点的引用
let next = head.next; // 这是重点,next 是下面递归返回的链表的最后一个节点;
next.next = head;
head.next = null; // 这也是重点,去除反转之前的第一个节点和第二个节点形成的环
// head.next === next,next.next === head
return rhead;
};
和第一种方法相比,使用了递归栈,空间换时间,依然是这个规律~
大家如果有更好的思路和解法,欢迎大家一起来讨论啊~
这是使用 JavaScript 对 LeetCode《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里: