【刷题日记】反转链表

60 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

206. 反转链表

给你单链表的头节点 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

方法一:迭代解法

这个解法也算是双指针解法,因为这里要设置两个指针,设置指针prev和curr,同时设置一个next代表curr的下一个,假如有一个链表1->2->3->4->5,令prev指向空,curr指向头结点也就是1,那么next就应该是curr.next也就是2,然后将curr向后移,让curr这一位置指向prev,此处也就是让2指向一,接着prev移到curr的位置,curr移到下一位,重复这段操作,直到遍历结束,通过判断curr指针的指向是否存在来判断循环是否应该继续。

代码就是下面这样

var reverseList = function(head) {
    let prev=null,curr=head;
    while(curr){
        const next=curr.next;
        curr.next=prev;
        prev=curr;
        curr=next;
    }
    return prev;
};

方法二:递归

这个方法中就只需要用到head了,就需要不断地调用这个函数,每次都让head下一位的指回来,这样改变了一个箭头的方向后,在移到下一位,再次调用函数改变下一个箭头指向,就这样不断循环调用,因此还需要有个限制条件,也就是head指针和head下一位都不为空,以此来为这个递归加个终止条件。 代码就是下面这样

var reverseList = function(head) {
    if(head=null || head.next=null){
        return head;
    }
    const p=reverseList(head.next);
    head.next.next=head;
    return p;
};

还有一种用递归这种思想的写法,这种是新建一个链表来存储反转后的链表,刚才那种是在原来的链表上反转,当然我个人认为刚才那种更简便一些,但多个方法也不错

代码长这样:

var reverseList = function(head) {
    //方法1:新建链表存储反转后的链表
    let res = new ListNode(-1);
    let cur = res;
    const reverse = (node) => {
        if(node === null) return;
        reverse(node.next);//后序遍历
        cur.next = node;//将节点从后往前存储到新建链表
        cur = cur.next;
    }
    reverse(head);
    cur.next = null;//避免成环
    return res.next;
};