合并 k 个排序链表,返回合并后的排序链表;
知识点
操作链表节点; 使用 vector的定义和使用;vector<ListNode*>& lists:这代表的是什么意思?
解题思路
解法一:暴力法-对待这样的问题应该是最首先想到的:先遍历所以元素放在数组中,然后排序,进而创建新链表
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {// 向量容器 结构体类型指针 &:取地址??
// 是不是队列算法 队列是属于算法,思路模式
// 这个vector容器里面存放的是lists链表,具体哪一个链表通过lists[i]来取,即K个链表的
// 首地址放在了一个连续的vector容器里面了
vector<int> vec;
ListNode* head; //定义指向链表的头指针
int i;// 循环变量
ListNode* result=new ListNode(-1);// 穿件链表
ListNode* p=result;// 指向结果列表的头指针
// 放在数组里面
for(i=0;i<lists.size();i++){
head =lists[i]; // 指向具体某一个链表的头指针
while(head!=NULL){
vec.push_back(head->val);
head=head->next;
}
}
// 排序
sort(vec.begin(),vec.end());
//创建新的链表
for(i=0;i<vec.size();i++){
p->next=new ListNode(vec[i]);
p=p->next;
}
return result->next;
}
};
Python 代码:
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
p = []
_lis = head = ListNode(0)
for i in lists:
while i:
p.append(i.val)
i = i.next
for j in sorted(p):
_lis.next = ListNode(j)
_lis = _lis.next
return head.next
解法二:优先级队列
用了一个大小为K的最小堆,通过用优先队列和自定义的降序来实现。先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中;用到了heapa模块;我们依次将最小元素从堆中取出,然后放入新链表,最后返回。
import heapq
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
p = []
_node = ListNode(0)
a = _node
for i in range(len(lists)):
if lists[i]:
heapq.heappush(p, (lists[i].val, i))
while p:
_, index = heapq.heappop(p)
head = lists[index]
a.next = head
a = a.next
if head.next:
heapq.heappush(p, (head.next.val, index))
lists[index] = head.next
head.next = None
return _node.next
C++:
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) {
return null;
}
ListNode dummyHead = new ListNode(0);
ListNode curr = dummyHead;
PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
});
for (ListNode list : lists) {
if (list == null) {
continue;
}
pq.add(list);
}
while (!pq.isEmpty()) {
ListNode nextNode = pq.poll();
curr.next = nextNode;
curr = curr.next;
if (nextNode.next != null) {
pq.add(nextNode.next);
}
}
return dummyHead.next;
}
}
解法三:分治法:这个方法将利用归并和排序的思想,利用递归方法和分治法将链表数组一直划分,变成越来越小的半链表数组,然后再对半链表数组进行排序,最后再通过递归的步骤将排好序的半链表数组合,合并成为越来越大的有序链表。简单来说就是一直在不停的对半划分,最后再结合在一起
Python 解法:
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if len(lists) == 0:
return None
return self.__merge_k_lists(lists, 0, len(lists) - 1)
def __merge_k_lists(self, lists, left, right):
if left >= right:
return lists[left]
mid = left + (right - left) // 2
lino1 = self.__merge_k_lists(lists, left, mid)
lino2 = self.__merge_k_lists(lists, mid + 1, right)
return self.__merge_two_sorted_list_node(lino1, lino2)
def __merge_two_sorted_list_node(self, list1, list2):
if list1 is None:
return list2
if list2 is None:
return list1
if list1.val < list2.val:
list1.next = self.__merge_two_sorted_list_node(list1.next, list2)
return list1
else:
list2.next = self.__merge_two_sorted_list_node(list1, list2.next)
return list2
class Solution {
public ListNode mergeKLists(ListNode[] lists){
if(lists.length == 0)
return null;
if(lists.length == 1)
return lists[0];
if(lists.length == 2){
return mergeTwoLists(lists[0],lists[1]);
}
int mid = lists.length/2;
ListNode[] l1 = new ListNode[mid];
for(int i = 0; i < mid; i++){
l1[i] = lists[i];
}
ListNode[] l2 = new ListNode[lists.length-mid];
for(int i = mid,j=0; i < lists.length; i++,j++){
l2[j] = lists[i];
}
return mergeTwoLists(mergeKLists(l1),mergeKLists(l2));
}
分治法:归并和排序,递归和分治;
小结
虽然说算法和具体语言是没有多大关系,只是实现的工具而已,但是极大地影响了我看别人用某种语言写的代码,进而不
明白他的算法思路是什么;