- 原题是
leetcode
206题 题目如下
/*
* @lc app=leetcode id=206 lang=javascript
*
* [206] Reverse Linked List
*/
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
}
解法一:利用数组 反转(缺点增加额外空间)
- 第一步:先将单链表所有节点(引用类型)存入一个数组
- 第二步:反转数组
- 第三步:数组第一个节点指向第二个节点,第二个节点指向第三个节点, ... ... 最后一个节点指向
null
- 将数组第一个元素(反转后的单链表第一个节点)返回,大功告成
完整代码:
var reverseList = function(head) {
// method 1 利用数组 反转(缺点增加额外空间)
let arr = [];
let root = head;
if (!head || !head.next) {
return head;
}
while(root) {
arr.push(root);
root = root.next;
}
arr.reverse();
let len = arr.length;
for (let i = 0; i < len; i++) {
arr[i+1] && (arr[i].next = arr[i+1]);
!arr[i+1] && (arr[i].next = null);
}
return arr[0]
};
解法二:利用两个指针 pre
curr
每次往下移动一位
完整代码:
var reverseList = function(head) {
if (!head || !head.next) {
return head;
}
let pre = head;
let curr = pre.next;
let last = curr.next;
pre.next = null; // 原来的第一个节点 必然指向 null
while (curr) {
last = curr.next; // 保留下一个节点
// 改变指向
curr.next = pre;
// pre curr 向下移动一位
pre = curr;
curr = last;
}
// 最后 curr 必然为 null,pre为之后一个元素,也就是新的单链表奶的似一个节点
return pre;
};
解法三:在单链表前增加一个辅助节点 pre
思路:
- 第一步:增加一个辅助节点
pre
- 第二步:从第二个节点开始,都插入到
pre
的后面
完整代码:
var reverseList = function(head) {
// method 3 在单链表前面 加一个辅助节点pre,
// 然后从第二个节点开始 插入到pre后面
function ListNode(val) {
this.val = val;
this.next = null;
}
if (!head || !head.next) {
return head;
}
let pre = new ListNode();
pre.next = head; // 辅助节点 pre
let root = head;
while (root) {
let n = root.next;
if (root === head) {
root.next = null;
} else {
root.next = pre.next;
pre.next = root;
}
root = n;
}
return pre.next;
}
解法四:递归
- 递归的方式我个人感觉没有其他方式 好理解
完整代码:
var reverseList = function(head) {
// method 4 递归去实现
if (!head || !head.next) {
return head;
}
let originHead = head;
let rootHead;
function recursive(node) {
let nextNode = node.next;
if(!nextNode) {
rootHead = node;
return node;
}
let n = recursive(nextNode);
n.next = node;
if (node === originHead) {
node.next = null;
return rootHead;
} else {
return node;
}
}
return recursive(head);
}
解法五:巧妙方案
- 该方法巧妙的利用了一个中间变量
temp
// method 5 终极方案
var reverseList = function(head) {
var temp = null;
while(head){
temp = {
val:head.val,
next:temp //这个 temp 每次循环指向的是上一个节点
};
head=head.next
}
return temp;
};
写在最后:
反转单链表是在面试环节经常遇到的题目,在遇到时,我们可以先说出解法一、二、三、四 到这里基本可以让面试官满意了,最后再拿出终极方案五,必有奇效