【LeetCode】 JavaScript实现 反转链表(三种思路)

206 反转链表 / 剑指 Offer 24. 反转链表

原题链接:206. 反转链表
在这里插入图片描述
原题链接:剑指 Offer 24. 反转链表
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {

};

解题思路:

①双指针法

  • 先存储当前结点的下一个结点
  • 把当前结点取出,指向上一个结点
  • 更换下一个结点继续迭代
var reverseList = function(head) {
   
    if(head==null){
        return null
    }
    var prev=null//前指针结点 可理解为创建了一个空链表
    var curr=head//当前指针结点
    var temp=null//临时结点
    //每次循环把当前结点指向前一个结点 把前结点和当前结点后移
    while(curr!=null){
        temp=curr.next //存当前结点的下一个结点,用于后移
        curr.next=prev  //当前结点指向前一个结点
        prev=curr       //前指针结点后移
        curr=temp       //当前指针结点后移
        //console.log(prev)
    }
    return prev //此时prev就是反转新链表的头结点
};

检测:console.log(prev) 每次循环后 打印prev的结果是

  1. [1]
  2. [2,1]
  3. [3,2,1]
  4. [4,3,2,1]
  5. [5,4,3,2,1]

②迭代法(与上一个思路类似,略复杂)

  • 让p指向第一个结点,通过指向使得p的位置在不断后移
  • q指向p的下一个结点,即每次循环需要放到第一个位置的结点,依次迭代
  • 让list指回q 确保链不断
var reverseList = function(head) {
   if(head==null){
        return null
    }
    var list=head 
    var p=list
    var q=null
    while(p.next!=null){
        q=p.next 
        p.next=q.next //断开当前第一个结点和当前第二个结点的连接,使第一个结点指向第三个结点
        q.next=list //断开当前第二个结点和第三个结点的连接,指向第一个结点
        list=q  //让list和q相连 
        //console.log(list)
    }
    return list
};

检测:console.log(list) 每次循环后 打印 list 的结果是

  1. [2,1,3,4,5]
  2. [3,2,1,4,5]
  3. [4,3,2,1,5]
  4. [5,4,3,2,1]

③递归调用法

  • 终止条件是当前节点或者下一个节点==null
  • 递归函数中每次返回的 cur 其实是最后一个节点
  • 在递归函数内部,改变的是当前节点的指向
var reverseList = function(head) {
   if(head==null||head.next==null){ 
        return head
    }
    var curr=reverseList(head.next) 
    head.next.next=head //head的下一个结点指向head
    head.next=null //防止循环指向 需要断开
    // console.log(curr)
    return curr
};

检测:console.log(curr)每次打印curr的结果是

  1. [5,4]
  2. [5,4,3]
  3. [5,4,3,2]
  4. [5,4,3,2,1]

具体动画详解可参考:动画演示+多种解法 206. 反转链表

92. 反转链表 II

原题链接: 反转链表 II

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} left
 * @param {number} right
 * @return {ListNode}
 */
var reverseBetween = function(head, left, right) {

}

解题思路:双指针+链表截取与拼接

var reverseBetween = function(head, left, right) {
    //定义一个哑节点 可能头节点有变化
    const dummyNode=new ListNode(0);
    dummyNode.next=head;

    let pre=dummyNode;
    //从虚拟节点走left-1 到left的前驱节点
    for(let i=0;i<left-1;i++){
        pre=pre.next;
    }
    //从pre再走right-left+1 到right节点
    let rightNode=pre;
    for(let i=0;i<right-left+1;i++){
        rightNode=rightNode.next;
    }
    //截取链表
    let leftNode=pre.next;
    let curr=rightNode.next;
    pre.next=null;
    rightNode.next=null;

    //反转链表
    reverseList(leftNode);
    //将反转后的链表拼接回去
    pre.next=rightNode;
    leftNode.next=curr;

    return dummyNode.next;
};

var reverseList=function(head){
    let pre=null;
    let curr=head;
    let temp=null;
    while(curr){
        temp=curr.next;
        curr.next=pre;
        pre=curr;
        curr=temp;
    }
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值