[路飞]_leetcode-206-反转链表

104 阅读2分钟

一、题目详情

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。\

  • 示例 1:

f1.png

输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
  • 示例 2:

f2.png

输入: head = [1,2]
输出: [2,1]

示例 3:

输入:head = [] 输出:[]  

提示:

链表中节点的数目范围是 [0, 5000] -5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

二、题解

提出问题

  • 在反转过程中,如何保留链表节点的下一个节点不丢失?

分析 迭代

  • 首先定义三个指针分为precurnext,并对指针进行初始化
  • pre指向 nullcur指向头节点,next指向cur所指向节点的下一个节点

image.png

  • cur指针所指向的节点指向pre所指向的节点

image.png

  • 移动precur所在的位置

image.png

  • 移动curnext所在的位置

image.png

  • 此时第一个节点已经反转完毕,将next指针指向cur所指向节点的下一个节点。

image.png

  • 重复执行上述操作,当cur指针指向null的时候说明,整个链表的反转执行完毕。

image.png

总结

  • 初始化哨兵节点prenullcur为当前节点head
  • 开始循环,记录 next为当前节点的下一个节点
  • 判断当前节点是否为null
  • 分别交换precurnext使其反转
  • 当cur为null时跳出循环

代码实现

代码一:

var reverseList = function(head) {
    if(head == null) return head;
    // 创建三个指针 pre指向虚拟头,cur指向未翻转位置的头结点
    // p指向未翻转位置头结点的下一个结点
    let pre = null;
    let cur = head;
    let p = head.next;
    // 当未翻转位置不为空的时候
    while(cur){
        // 让未翻转部分指向,我反转部分的头结点
        cur.next = pre;
        pre = cur;
        (cur = p) && (p = p.next);
    }
    return pre;
};

代码二:

 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    if(!head) return null
    var pre=null
    var cur = head
    while(cur){
        [cur.next,pre,cur] = [pre,cur,cur.next]
    }
    return pre
};

以上就完成了反转链表,欢迎讨论