算法设计课第二周作业

Merge k Sorted Lists

题目描述

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:

Input:
[
  1->4->5,
  1->3->4,
  2->6
]
Output: 1->1->2->3->4->4->5->6

实验思路

  1. 因为是已经是排好序的数组,所以没必要遍历一遍生成一个新的数组再进行递归排序,这样不仅浪费内存,也浪费时间。
  2. 所以采用分治的思想,把这个vector中的lists分为两半,再进行排序。
  3. 递归步骤2。
  4. 合并并排序。
    ## 代码展示
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {
    }
};
class Solution {
public:

    ListNode* mergeLists(ListNode* left, ListNode *right){
        //如果左边的链表为空,则返回右边的链表 
        if(!left){
            return right;
        }
        //如果右边的链表为空,则返回左边的链表 
        if(!right){
            return left;
        }
        //变量ptr用于记录最后返回的合并后的链表的头 
        ListNode* ptr = NULL;
        //变量pptr用于整合两个链表 
        ListNode** pptr = &ptr;

        while(left || right){
        //如果左边的链表不为空且大于右边的链表,则把该节点从原链表中取出,将NULL赋值给该节点的next指针其实就相当于把它从原来的链中“打断”            
            if((left && !right) || (left && (left->val < right->val))){
                *pptr = left;
                ListNode* temp = left->next;
                left->next = NULL;
                ptr = &((*pptr)->next);
                left = temp;
            }else{
                *pptr = right;
                ListNode* temp = right->next;
                right->next = NULL;
                pptr = &((*pptr)->next);
                right = temp;
            }
        }

        return ptr;
    }

    //将链表数组递归分为左右两半 
    ListNode* mergeK(const vector<ListNode*>::iterator begin, const vector<ListNode*>::iterator end){

        if(begin == end){
            return nullptr;
        }

        if(distance(begin, end) == 1){
            return *begin;
        }

        int mid = distance(begin, end)/2;
        ListNode* left = mergeK(begin, begin + mid);
        ListNode* right = mergeK(begin + mid, end);

        return mergeLists(left, right);
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        auto begin = lists.begin();
        auto end = lists.end();
        return mergeK(begin, end);
    }
};

实验总结

pptr的使用,减少了内存的浪费,还是用原来的链表节点已分配的内存。

猜你喜欢

转载自blog.csdn.net/weixin_38873581/article/details/82728318