题目
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
输入: head = [1,2,3,4,5] 输出: [5,4,3,2,1]
题解
第一种
我们在函数中先判断检查head是否为空,如果为空则说明链表为空我们直接返回null,然后我们声明了两个变量prev和node,默认值分别为null和head,这两个变量我们用于在遍历链表时进行节点的反转操作,然后我们使用一个循环,循环条件为node不为空,这能够保证我们遍历链表直到最后一个节点,在循环中我们先声明了一个变量next,用于保存了当前节点node的下一个节点,然后我们将当前节点的next指针指向前一个节点prev,这样就实现了节点的反转,然后我们更新一下prev变量为当前节点node并将其作为下一个节点的前一个节点,然后我们将当前节点node更新为下一个节点next,继续循环遍历链表,当循环结束后,我们将prev返回出去即可
var reverseList = function (head) { if (!head) return null; let prev = null; let node = head; while (node) { const next = node.next; node.next = prev; prev = node; node = next; } return prev; };
第二种
我们在函数中先使用条件判断语句判断一下当前head为空或者head下一个节点为空,如果是则说明当前head只有一个节点,这样的情况下则无需反转,我们直接返回原链表的头节点head即可,如果不是我们则声明一个变量newHead,它保存了调用reverseList函数传入参数head.next的结果,我们这里使用了递归调用,因为这样可以把链表的反转操作拆分成更小的部分,然后我们在链表反转的过程中,将当前节点head的下一个节点的next指针指向当前节点实现反转,然后我们将当前节点head的next指针设置为null,这样就断开了当前节点与下一个节点的连接,避免了形成循环链表,最后我们返回变量newHead即可,这种方法比较第一种方法虽然很不错,不过在处理大型链表时有可能会导致堆栈溢出的问题
var reverseList = function(head) { if(!head || !head.next){ return head; } const newHead = reverseList(head.next); head.next.next = head; head.next = null; return newHead; };