23 Merge k Sorted Lists

来源:互联网 发布:你是我兄弟网络大电影 编辑:程序博客网 时间:2024/05/17 04:31

归并多组有序的链表

刚刚在LeetCode上刷了一道题目,显示是hard级别的,但是自己居然编译痛过之后一遍就AC了,想想挺开心的,就写篇博客分析一下这道题目,并且分析这道题目的时间复杂度等
先看题目:

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
以下是C++的实现入口:

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* mergeKLists(vector<ListNode*>& lists) {    }}

题目中给定一个容器,里面存储的是每一个链表的第一个节点,所以我们首先需要获得所有的开始节点,然后两两归并。我的思路是将第一个链表作为head,以后开始顺序遍历容器,每一次取出容器内的一个链表,将它和之前已经合并了的链表合并,直至容器为空,然后返回head就好了。
值得一提的是在我第一遍提交的时候出现了一个报错:reference binding to null pointer of type ‘struct ListNode*’ 这主要是因为我访问了不存在的容器元素,最开始的时候并没有考虑到容器为空的情况,所以出现这个报错;另外,在容器的大小小于等于1的时候都是不需要归并的,直接返回就好了。
下面是我的程序代码:

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* mergeKLists(vector<ListNode*>& lists) {        if (lists.size() > 1) {            ListNode* head = *(lists.begin());            vector<ListNode*>::iterator it = lists.begin();            ListNode* temp1 = NULL;            ListNode* temp2 = NULL;            ListNode* temp = NULL;            int index = 0;            int number1 = 0;            int number2 = 0;            for (it = lists.begin() + 1; it !=                 lists.end(); it++) {                temp1 = head;                temp2 = *it;                index = 0;                while(temp1 != NULL || temp2 != NULL) {                    number1 = temp1 != NULL ? temp1 ->                     val : INT_MAX;                    number2 = temp2 != NULL ? temp2 ->                     val : INT_MAX;                    if (number1 < number2) {                        if (index == 0) {                            head = temp1;                            temp1 = temp1 -> next;                            head -> next = NULL;                            temp = head;                            index = 1;                        } else {                            temp -> next = temp1;                            temp1 = temp1 -> next;                            temp = temp -> next;                            temp -> next = NULL;                            }                    } else if (number1 >= number2) {                        if (index == 0) {                            head = temp2;                            temp2 = temp2 -> next;                            head -> next = NULL;                            temp = head;                            index  =1;                        } else {                            temp -> next = temp2;                            temp2 = temp2 -> next;                            temp = temp -> next;                            temp -> next = NULL;                            }                    }                }            }            return head;        } else if (lists.size() == 1) {            return *(lists.begin());        } else {            return NULL;        }    }};

可以看出这道题的逻辑实现并不复杂,在草稿纸上画一画,对应的实现出来就好了,只是涉及指针的问题总是很困扰人,所以纪念一下。

下面分析这个算法的时间复杂度:
假设容器的大小为M, 每一个链表的平均长度是N那么,遍历容器需要M的时间,链表为N,则时间复杂度为O(m * n).空间复杂度是O(1).

原创粉丝点击