剑指 Offer II 026. 重排链表-js

1、通过快慢找到中点,分为前后两个链表,后一链表翻转,之后再合并,时间复杂度O(n)

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 无返回值:不要返回任何东西,而是修改head
 * @return {void} Do not return anything, modify head in-place instead.
 */
var reorderList = function(head) {
    let dummy=new ListNode(0);
    dummy.next=head;
    let slow=dummy;
    let fast=dummy;
    while(fast!=null){
        slow=slow.next;
        fast=fast.next;
        if(fast!=null){
            fast=fast.next;
        }
    }
    let temp=slow.next;
    slow.next=null
    link(head,reverseList(temp),dummy);
};
var link=function(node1,node2,head){
    let prev=head;
    while(node1!=null&&node2!=null){
        let tempNode=node1.next;

        prev.next=node1;
        node1.next=node2;
        prev=node2;
        
        node1=tempNode;
        node2=node2.next;
    }
    // 若为奇数
    if(node1!=null){
        prev.next=node1;
    }
}

// 翻转链表
var reverseList=function(list){
    if(list==null){
        return null
    }
    let prev=null;
    let cur=list;
    while(cur!=null){
        let next=cur.next;
        cur.next=prev;
        prev=cur;
        cur=next;
    }
    return prev
}

2、遍历遍历找到中点

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 无返回值:不要返回任何东西,而是修改head
 * @return {void} Do not return anything, modify head in-place instead.
 */
var reorderList = function(head) {
    let listLength=1;
    for(let node=head;node!=null;node=node.next){
        listLength++;
    }
    let node=head;
    for(let i=0;i<listLength/2-1;i++){
        node=node.next;
    }
    let lastHalf=node.next;
    node.next=null;
    link(head,reverseList(lastHalf))
};
var link=function(node1,node2){
    // let dummy=new ListNode(0);
    let prev=new ListNode(0);//用来指向头节点
    // 一替一个接进去
    while(node1!=null&&node2!=null){
        prev.next=node1;
        // 保存node1的下一个指针,为了一行将node1接上node2,且不丢失当前其后面的节点
        let node1next=node1.next;
        node1.next=node2;
        
        prev=node2;
        node1=node1next;
        node2=node2.next;

    }
    // 对于一个链表中还没接完的情况,即奇数情况
    if(node1!=null){
        prev.next=node1;
    }
}

// 翻转链表
var reverseList=function(list){
    if(list==null){
        return null
    }
    let prev=null;
    let cur=list;
    while(cur!=null){
        let next=cur.next;
        cur.next=prev;
        prev=cur;
        cur=next;
    }
    return prev
}

相比方法1,增加了遍历的时间,并且在主函数中没有使用dummy,只是在合并link函数中使用了dummy。(在主函数中实际不需要dummy)
在这里插入图片描述

注:为什么Link中写不写返回值,head都改变了?为什么在函数中改变了head,主函数中没变??
因为在主函数中head还是是链表第一个节点的(1),(1)只是指向变了
而且在其他函数中作为参数永远是传值调用,你只能修改head指向的内容,不能修改head本身。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值