LeetCode(92+206):反转单链表

入门版(206题)

题目描述

LeetCode(92+206):反转单链表

解题思路:迭代

使用cur和pre两个指针,一前一后(一左一右)地指向两个相邻节点

在每一轮迭代中:

  • 用临时指针保存pre的next

  • 让pre的next(掉头)指向cur

  • cur和pre都沿着链表原来的方向,向前(右)走一步

当pre为空时,迭代结束

此时cur就是新链表的头节点,返回cur即可

需要注意的是:

在迭代开始之前,需要处理链表头节点的next为空(否则就会形成环)

代码实现(Javascript)

var reverseList = function(head) {
    if(!head || !head.next){
        return head
    }

    var cur = head
    var pre = head.next
    var temp = null
    cur.next = null

    while(pre){
        temp = pre.next
        pre.next = cur
        cur = pre
        pre = temp
    }

    return cur
};

进阶版(92题)

题目描述

LeetCode(92+206):反转单链表

解题思路

基本的思路是:对上一题的反转单链表进行简单的改造,即 将"反转"的具体操作交给一个辅助函数来完成

这个辅助函数接收2个参数:子链表头节点和反转次数,并返回 反转后子链表的头节点

因此,在主函数中,我们只需要将原链表的第m个节点传入辅助函数,并让第m-1个节点的next指向返回结果即可

主函数代码如下:

var reverseBetween = function(head, m, n) {
    if(!head) {
        return null
    }
    if(m===n){
        return head
    }

    var cur = head
    var dummy = new ListNode(-1)
    dummy.next = head
    var prev = dummy

    for(let i=0;i<m-1;i++){
        prev = cur
        cur = cur.next
    }
    prev.next = reverseList(cur, n-m)
    return dummy.next
};

在辅助函数中,除了进行指定次数的迭代之后,我们还需要让 子链表的头部节点的next 指向原链表的第n+1个位置(从而保证原链表的完整性)

var reverseList = function(head,t) {
    if(!head){
        return null
    }
    if(!head.next){
        return head
    }

    var cur = head
    var pre = head.next
    var temp = null
    
    for(let i=0;i<t;i++){//反转t次
        temp = pre.next
        pre.next = cur
        cur = pre
        pre = temp
    }

    head.next = pre
    return cur
};

在迭代结束后,pre恰好就指向原链表的第n+1个节点

因此,直接将head的next指向pre即可