023 Merge k Sorted Lists [Leetcode]

来源:互联网 发布:淘宝店招牌 编辑:程序博客网 时间:2024/06/12 05:24

题目内容:

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

题目分析:
k个排过序的链表,要将它们合并起来就要求能够在较短的时间内将当前的k个数进行排序,并且能够高效得支持数字的增删操作。
可以使用的方法有:败者树,堆排序,这两个算法在插入、删除节点的时候复杂度都为O(n)。

处理流程:
1. 使用每个链表起始的节点,共k个节点,进行堆排序,复杂度O(klogk)
2. 之后从这k个节点中选择一个最大的,插入到新的链表中去。
3. 被选中的那个链表的节点的下一个节点如果存在,插入到堆中去。
4. 回到步骤2

结束条件为堆中元素少于等于1个,即只有最后一个链表或没有链表剩余。

使用堆的代码:
需要注意的是,priority_queue默认实现的是最大堆,而stl中的比较函数默认是通过“<”符号来实现,因此实现最小堆的时候要重写比较函数,将<重写为>。

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */struct cmp {    bool operator()(ListNode *n1, ListNode *n2) {        return n1->val > n2->val;    }};class Solution {public:    ListNode *mergeKLists(vector<ListNode *> &lists) {        priority_queue<ListNode *, vector<ListNode *>, cmp> min_heap;        for(int i = 0; i < lists.size(); ++i) {            if(lists[i] != NULL)                min_heap.push(lists[i]);        }        ListNode *pre_head(new ListNode(0)), *curr(pre_head);        while(min_heap.size() > 1) {            curr->next = min_heap.top();            min_heap.pop();            curr = curr->next;            if(curr->next != NULL)                min_heap.push(curr->next);        }        if(min_heap.size() == 1) {            curr->next = min_heap.top();            min_heap.pop();        }        ListNode *head = pre_head->next;        pre_head->next = NULL;        delete pre_head;        return head;    }};

使用败者树的代码:

/** * 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) {        int size = lists.size();        if (size == 0)            return NULL;        int *key = new int[size + 1];        key[size] = INT_MIN;        ListNode **elements = new ListNode*[size];        int *loser = new int[size];        for (int i = 0; i < size; i++) {            elements[i] = lists[i];            loser[i] = size;            if (elements[i] != NULL)                key[i] = elements[i]->val;            else key[i] = INT_MAX;        }        for (int i = 0; i < size; i++) {            adjust(loser, key, i, size);        }        ListNode *head = NULL, *curr = NULL;        while (true) {            if (key[loser[0]] == INT_MAX) {                break;                curr->next = NULL;            }            if (head == NULL) {                head = elements[loser[0]];                curr = elements[loser[0]];                elements[loser[0]] = elements[loser[0]]->next;            }            else {                curr->next = elements[loser[0]];                curr = curr->next;                elements[loser[0]] = elements[loser[0]]->next;            }            if(elements[loser[0]] != NULL)                key[loser[0]] = elements[loser[0]]->val;            else                 key[loser[0]] = INT_MAX;            adjust(loser, key, loser[0], size);        }        return head;    }    void adjust(int loser[], int key[], int k, int size) {        for (int i = (size + k)/2; i > 0; i /= 2) {            if (key[loser[i]] < key[k]) {                int temp = k;                k = loser[i];                loser[i] = temp;            }        }        loser[0] = k;    }};
0 0
原创粉丝点击