LeetCode [23] 合并K个有序链表

题目链接:23. 合并 K 个升序链表 - 力扣(LeetCode)

思路:

前有合并两个有序链表,感觉比较简单,没有认为合并K个升序链表难,其实直观上算法都是比较简单:首先对比每一个链表头部元素,找出最小的,放在目标链表中,更新这个链表头,直到遍历所有链表。主要是一些细节处理上。

ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.size() == 0) return nullptr;
        //依旧是双指针,一个用来滑动更新,另一个用来记录返回的头
        ListNode* head = new ListNode(-1);
        ListNode* res = head;
        while(lists.size() != 0)
        {
            //对于只有一个链表的,直接返回
            if(lists.size() == 1)
            {
                head->next = lists[0];
                break;
            }
            int  min = __INT_MAX__;
            int idx = 0;
            //从第一个开始遍历
            for(int i = 0; i < lists.size(); i++)
            {
                //这里挺重要
                //如果某个元素已经为空链表,删除这个链表
                //然后从i需要更新为i-1,否则continue后会i++,跳过一个元素
                if(lists[i] == nullptr) 
                {
                    auto iter = lists.begin();
                    lists.erase(i + iter);
                    i = i-1;//重要!!!
                    continue;
                }
                //找到最小的链表头,及链表在vector中的idx
                if(min > lists[i]->val) 
                {
                    min = lists[i]->val;
                    idx = i;
                }
            }
            //此时检测list.size(),因为最后一个链表为空后
            //上述会删除链表导致lists[]也为空
            if(lists.size() == 0) break;
            //head->next指向此次寻找到的最小头
            head->next = lists[idx];
            //head更新
            head = head->next;
            // lists[idx]位置的链表头更新
            lists[idx] = lists[idx]->next;
            if(head->next) head->next = nullptr;//断掉加入head的节点与原链表的关系
            
        }
        return res->next;
    }

最近又重写了一遍,相当于把代码重构了一把,去掉不必要的

ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.size() == 0) return nullptr;
        ListNode* Head = new ListNode();
        ListNode* res = Head;
        while(lists.size() != 0)
        {
            int min = __INT_MAX__;
            int idx = 0;
            for(int i = 0; i < lists.size(); i++)
            {
                if(lists[i] == nullptr) 
                {
                    lists.erase(i+lists.begin());
                    //这里需要注意,删除一个list之后,lists的size()已经改变,需要改变当前的索引i
                    i--;
                    continue;
                }
                if(min > lists[i]->val)
                {
                    min = lists[i]->val;
                    idx = i;
                }
            }
            //每次结束需要判断lists是否已经删空,如果空了,就要break出while
            if(lists[idx] == nullptr) break;
            Head->next = lists[idx];
            Head = Head->next;
            lists[idx] = lists[idx]->next;
        }
        return res->next;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值