Leetcode.23.Merge k Sorted Lists

题目

给定k个有序链表, 将这些链表合并为一个新链表.

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

基础方法

struct ListNode {
  int val;
  ListNode *next;
  ListNode(int x) : val(x), next(NULL) {}
};

ListNode* vecToListNodes(vector vec) {
  if (vec.size() == 0){
      return NULL;
  }

  vector::iterator iter = vec.begin();
  ListNode *header = new ListNode(*iter);
  ListNode *temp = header;
  iter++;

  while(iter != vec.end()) {
    cout << *iter << endl;
    ListNode *node = new ListNode(*iter);
    temp->next = node;
    temp = node;
    iter++;
  }

  return header;
}

思路1

将k个链表的数都取出来, 放到一个数组, 对数组进行排序, 将数组转化为一个链表.
时间复杂度O(NlogN)(N表示所有节点总量)
空间复杂度O(N)

ListNode* mergeKLists(vector& lists) { 
  vector vec;
  for(int i = 0;i < lists.size();i++) {
    ListNode *tmp = lists[i];
    while (tmp != NULL){
        vec.push_back(tmp->val);
        tmp = tmp->next;
    }
  }
  sort(vec.begin(),vec.end());
  return vecToListNodes(vec);
}

思路2

每次找到k个链表中最小的数, 加入到新链表中. 但是时间效率太低, 空间效率也不高.
时间复杂度O(kN)
空间复杂度O(n)

ListNode* mergeKLists(vector& lists) {
  vector temp = lists;
  ListNode *header = NULL;
  ListNode *res = NULL;

  while(true) {
      int min = INT_MAX;
      int minIndex = 0;
      bool isEnd = true;
      for(int i = 0;i < temp.size();i++) {
          if (temp[i] != NULL) {   
              isEnd = false;
          }else {
              continue;
          }

          if (min > temp[i]->val) {
              min = temp[i]->val;
              minIndex = i;
          }
      }
      if (isEnd) {
          break;
      }
   
      temp[minIndex] = temp[minIndex]->next;
      ListNode *node = new ListNode(min);
      if (res == NULL) {
          header = node;
          res = node;
      } else {
          res->next = node;
          res = res->next;
      }
  }
  return header;
}

思路3

采用二分法, 两两合并.
时间复杂度O(Nlogk)
空间复杂度O(1)

ListNode* merge2Lists(ListNode *list1, ListNode *list2) { 
  ListNode *tmp = new ListNode(0);
  ListNode *header = tmp;

  while (list1 != NULL && list2 != NULL) {
    if (list1-> val < list2->val) {
        tmp->next = list1;
        list1 = list1->next;
    } else {
        tmp->next = list2;
        list2 = list2->next;
    }
    tmp = tmp->next;
  }

  if (list1 != NULL){
      tmp->next = list1;
  }

  if (list2 != NULL) {
      tmp->next = list2;
  }

  return header->next;
}

ListNode* mergeKLists(vector& lists) {
  if (lists.size() == 0) {
      return NULL;
  }
  vector temp = lists;
  ListNode *header = NULL;
  ListNode *res = NULL;

 while (temp.size() > 1) 
 {
   vector tmp;
   for(int i = 0;i < temp.size();) {
       ListNode *newListNode;
       if (i + 1 < temp.size()) {
            newListNode = merge2Lists(temp[i], temp[i+1]);
            i += 2;
       } else {
           newListNode = temp[i];
           i += 1;
       }
       tmp.push_back(newListNode);
   }
   temp = tmp;
 }

  return temp.front();
}

总结

二分法两两合并是效率最高的, 复杂问题往往需要拆分为简单问题.

你可能感兴趣的:(Leetcode.23.Merge k Sorted Lists)