leetcode-个人题解23

LEETCODE专题


23. Merge k Sorted Lists

题目要求:
这里写图片描述


题目意思很简单,就是给定许多条有序链表,然后让我们合并成一条有序链表再返回即可。

  • 下面简要介绍一下2种思路:

    1. 第一种就是比较暴力的方法:在所有的链表中取一个最小的数,然后将对应的链表结点指针往后移一位,同时新建一个链表结点;此后重复所有步骤,只是新建的链表结点要和之前的链表结点相连,其实也就是一个next指针的的问题。
      当然在这个过程中要注意2点:1.注意结束条件是所有链表都已经走完;2.要判断下链表是否已经走完,才能决定比不比较该链表结点的值

      • 这种方法虽然思路简单些,但是实现起来其实非常的繁琐,不仅每次都要比较k - 1次,而且还要注意很多判断条件,以防内存访问错误(比如访问NULL)。而且每一次比较都要扫描k次,假设一共有n个结点的话,就需要扫描n次,时间复杂度就成了O(nk)了。
    2. 第二种方法就是归并排序,做过leetcode第21题的话就会发现,21题简直就是为23题量身订制的接口!
      将k个链表分成k / 2份,每2个链表进行一次归并,这样就会得到k / 2个新链表。重复上述过程,链表数目会呈现这样的变化规律:k -> k / 2 -> k / 4 -> … -> 1,最后只存在1条链表就可以返回该链表了。其中每一趟都扫描所有链表1次。

      • 这种方法思路简单,而且最主要的是可以充分利用已有资源。假设一共有n个结点,那时间复杂度就是O(n logk)了。

下面直接上code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* merge2Lists(ListNode* l1, ListNode* l2) {
        int min;

        // get the smaller value of the two value
        if (l1 == NULL && l2 == NULL) {
            return NULL;
        } else if (l2 == NULL || (l1 != NULL &&
                    l1->val < l2->val) ) {
            min = l1->val;
            l1 = l1->next;
        } else {
            min = l2->val;
            l2 = l2->next;
        }

        ListNode * newListNode = new ListNode(min);
        ListNode * newhead = newListNode;

        while (l1 != NULL || l2 != NULL) {
            if (l2 == NULL || (l1 != NULL &&
                    l1->val < l2->val)) {
                min = l1->val;
                l1 = l1->next;
            } else {
                min = l2->val;
                l2 = l2->next;
            }
            newListNode->next = new ListNode(min);
            newListNode = newListNode->next;
        }

        return newhead;
    }

    /* merge 2 lists to produce a list twice as large
     * as the former list. Each pass will take
     * O(n). Totally, it has logk passes and thus its
     * time complexity is O(nlogk).
     */

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if (lists.size() == 0) {
            return NULL;
        }
        ListNode * l1, * l2;
        while (lists.size() > 1) {
            l1 = lists.back();
            lists.pop_back();
            l2 = lists.back();
            lists.pop_back();
            lists.insert(lists.begin(), merge2Lists(l1, l2) );
        }
        return lists[0];
    }
};

时间复杂度:O(n logk)

猜你喜欢

转载自blog.csdn.net/m0_37576233/article/details/78127447