[路飞]-leetcode92,206反转链表

163 阅读1分钟

我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

206. 反转链表

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

解题思路:

普通解法
  1. 我们首先需要一个变量cur代表指向头节点, pre暂时为null 不赋值, 第一个循环我们先将cur.next指向 pre 如下图中第一个链表所示。 这样的操作,断掉了之前的cur.next指向,并赋上了一个pre

  2. 我们将pre cur next 往后移动重复以上操作。

  3. 最终结果就是如下图最后一个链表所示,pre 到达了原始链表最末。则返回pre即可。

在链表的解题思路中一定要注意某个节点next指向是否断了。否则最终返回结果会造成链表里有环。

image.png

var reverseList = function (head) {
    let cur= head,pre=null;
    while(cur){
        let next = cur.next
        cur.next = pre //断掉当前指向并指向新的pre
        pre = cur  
        cur = next // 向后移动继续遍历
    }
}

递归解法

var reverseList = function(head){
   if(!head ||!head.next) return head //递归终止条件
   var newhead = reverseList(head.next)
   head.next.next = head // head.next看成一个整体然后它的next指向head
   head.next = null
   return newhead
}

image.png

92. 反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 image.png

解题思路:

如上图:首先声明一个虚拟头节点dummy指向head, 通过left的值 将pre指针移动到需要翻转链表的头节点的上一个节点,然后声明两个变量cur``next 分别为翻转列表的当前指针和下个指针,循环的次数是right-left次。

我们需要将cur.nextnext保存,第一步将pre.next指向cur.next cur.next指向next.next next.next指向pre.next 这样就完成了翻转链表的前两个节点的翻转。我们还需要继续,cur往后移动,继续上一部操作。 直到循环次数遍历完毕。则链表翻转完成。

var reverseBetween = function(head, left, right) {
    // 需要一个虚拟头节点
    const dummy = {next:head}
    let pre = dummy 
    // 移动pre到翻转链表的头节点上一个节点
    for(let i = 0; i<left-1; i++) {
        pre = pre.next
    }
     let cur = pre.next,next 
     // 翻转逻辑
     for(let i =0; i<right-left; i++){
         let next = cur.next;
         cur.next = next.next;
         next.next = pre.next
         pre.next = next;
     }
     return dummy.next
}

结束语

如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~