【小f的刷题笔记】(JS)链表 - 合并 k 个有序链表 LeetCode23 - 顺序&合并&暴力三种方法

【链表】

合并 k 个有序链表:

🌟 想办法从一堆节点中找到最小的那个节点

看了很多题解,主要是以下四种方法(优先队列我还没有写出来,先遗留着):

顺序合并
分治合并(归并)
暴力求解
优先队列


LeetCode303

链接:

23.合并 k 个升序链表

题目:

在这里插入图片描述


思路1 - 顺序合并:

-> 每次都看作合并两个有序链表,就是去遍历一遍链表数组,其余和 21.合并两个有序链表

代码:
var mergeKLists = function(lists) {
    let ans = null
    // 顺序去拿每个链表,两两合并,合完作为一个新数组,再跟下一个数组合并
    for(let i=0; i<lists.length; i++) {
        ans  = mergeTwoLists(ans, lists[i])
    }
    return ans
};

// 第21题合并两个数组的方法
var mergeTwoLists = function(a, b) {
    if(a == null || b == null) {
        return a != null ? a : b
    }
    const dummy = new ListNode(-1)
    let p = dummy, aPtr = a, bPtr = b
    while(aPtr != null && bPtr != null) {
        if(aPtr.val < bPtr.val) {
            p.next = aPtr
            aPtr = aPtr.next
        } else {
            p.next = bPtr
            bPtr = bPtr.next
        }
        p = p.next
    }
    p.next = aPtr!==null ? aPtr : bPtr
    return dummy.next
}

思路2 - 分治合并(归并):

-> 同思路1一样,每次都看作合并两个有序链表,但不是按顺序的两两合并,这里用到了递归,分组合并链表,比上一种方法在时间上会更快一些

代码:
var mergeKLists = function(lists) {
    return merge(lists, 0, lists.length-1)
};

// 分治思想
var merge = function(lists, l, r) {
    if(l===r) {
        return lists[l]
    }
    if(l>r) {
        return null
    }
    let mid = (l+r) >> 1
    return mergeTwoLists(merge(lists, l, mid), merge(lists, mid+1, r))
};

// 第21题合并两个数组的方法
var mergeTwoLists = function(a, b) {
    if(a == null || b == null) {
        return a != null ? a : b
    }
    const dummy = new ListNode(-1)
    let p = dummy, aPtr = a, bPtr = b
    while(aPtr != null && bPtr != null) {
        if(aPtr.val < bPtr.val) {
            p.next = aPtr
            aPtr = aPtr.next
        } else {
            p.next = bPtr
            bPtr = bPtr.next
        }
        p = p.next
    }
    p.next = aPtr!==null ? aPtr : bPtr
    return dummy.next
}

思路3 - 暴力求解:

-> 把所有链表的值拿出来放到一个数组里去,数组升序排序,再把数组的值连成一个新的链表

代码:
var mergeKLists = function(lists) {
    // 定义一个数组存储所有链表的值
    const temp = []
    if(lists.length === 0) return null
    for(let i=0; i<lists.length; i++) {
        // 去遍历每个内部数组,只要有值就push到数组中
        while(lists[i]) {
            temp.push(lists[i].val)
            lists[i] = lists[i].next  // 这个其实就相当于i++
        }
    }
    // 时刻提防空数组 二维空数组也是
    if(temp.length === 0) return null
    // 升序排序 其实括号里不写也没事 默认升序
    temp.sort((a,b) => a-b);
    // 数组排好序了 再把它们变成一个新链表
    // 还是跟之前一样 定义一个哑结点
    const muddy = new ListNode(-1)
    // p是游标
    let p = muddy
    for(let i=0; i<temp.length; i++) {
        // 依次把数组的值实例化为链表节点,赋值给p.next,然后p指针后移
        p.next = new ListNode(temp[i])
        p = p.next
    }
    return muddy.next
};

写在最后:
js知识还不大够,优先队列暂时先得遗留着
加油叭!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值