Leetcode 23. 合并 K 个升序链表

文章提供了三种不同的编程解决方案来合并K个升序链表,主要利用了C++中的lambda表达式和优先队列以及Go语言中的二叉堆。所有方法的目标是创建一个新的链表,其中节点按升序排列。第一种方法使用了lambda优先队列,第二种和第三种方法分别在二刷和三刷时采用,包括了自解和归并排序的思路。
摘要由CSDN通过智能技术生成

题目

在这里插入图片描述
Leetcode 23. 合并 K 个升序链表

代码(首刷看解析,lambda优先队列)

 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        auto cmp = [](ListNode* a, ListNode* b) { return a->val > b->val; };
        priority_queue<ListNode*, vector<ListNode*>, decltype(cmp)> q(cmp);
        for(auto& node : lists) {
            if(node)    // 防止插入空指针
                q.push(node);
        }
        auto head = new ListNode(0);
        auto p = head;
        while(!q.empty()) {
            p->next = q.top();
            p = p->next;
            q.pop();
            if(p->next) 
                q.push(p->next);
        }
        return head->next;
    }
};

代码(8.7 二刷自解)

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        auto cmp = [](ListNode* a, ListNode* b) { return a->val > b->val;};
        priority_queue<ListNode*, vector<ListNode*>, decltype(cmp)> q(cmp);
        for(auto node : lists) {
            if(node) q.push(node);
        }
        auto dummy = new ListNode(0);
        auto p = dummy;
        while(!q.empty()) {
            auto top = q.top();
            p->next = top;
            q.pop();
            if(top->next)
                q.push(top->next);
            p = p->next;
        }
        return dummy->next;
    }
};

学习GO的小根堆

func mergeKLists(lists []*ListNode) *ListNode {
    if len(lists) == 0 {return nil}
    h := IntHeap{}
    heap.Init(&h)
    for _, list := range lists {
        if list != nil {
            heap.Push(&h, list)
        }
    }
    dummy := &ListNode{}
    p := dummy
    for h.Len() > 0 {
        top := heap.Pop(&h).(*ListNode)
        p.Next = top
        p = p.Next
        if top.Next != nil {
            heap.Push(&h, top.Next)
        }
    }
    return dummy.Next
}
type IntHeap []*ListNode
func (h IntHeap) Less(i, j int) bool { return h[i].Val < h[j].Val}
func (h IntHeap) Swap(i, j int) {h[i], h[j] = h[j], h[i]}
func (h IntHeap) Len() int { return len(h) }
func (h *IntHeap) Push(x interface{}) {*h = append(*h, x.(*ListNode))}  // 这两个函数顶层是interface{}
func (h *IntHeap) Pop() interface{} {
    n := len(*h)
    ans := (*h)[n-1]
    *h = (*h)[:n-1]
    return ans
}

代码(9.8 三刷看解析 归并)

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return merge(lists, 0, lists.size()-1);
    }
    ListNode* merge(vector<ListNode*>& lists, int l, int r) {
        if(l == r)
            return lists[l];
        if(l > r)
            return nullptr;
        int mid = (l+r)/2;
        return merge2Lists(merge(lists, l, mid), merge(lists, mid+1, r));
    }
    ListNode* merge2Lists(ListNode* a, ListNode* b) {
        if(!a || !b) 
            return a ? a : b;
        ListNode head, *tail = &head;
        auto aptr = a, bptr = b;
        while(aptr && bptr) {
            if(aptr->val < bptr->val) {
                tail->next = aptr;
                aptr = aptr->next;
            } else {
                tail->next = bptr;
                bptr = bptr->next;
            }
            tail = tail->next;
        }
        if(aptr) tail->next = aptr;
        else tail->next = bptr;
        return head.next;
    }
};

自解

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        auto cmp = [](auto& a, auto& b) { return a->val > b->val; };
        priority_queue<ListNode*, vector<ListNode*>, decltype(cmp)> q(cmp);
        for(auto& l : lists) {
            if(l)
                q.push(l);
        } 
        ListNode ans, *tail = &ans;
        while(!q.empty()) {
            auto top = q.top();
            q.pop();
            tail->next = top;
            tail = tail->next;
            if(top->next)
                q.push(top->next);
        }
        return ans.next;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值