23.合并 K 个升序链表
方法一:暴力法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode ans=null;
for(int i=0;i<lists.length;i++){
//每次循环看作是两个链表的拼接 ,每次都更新ans链表 然后再赋值给ans!
ans=mergeTwoLists(ans, lists[i]);
}
return ans;
}
public ListNode mergeTwoLists(ListNode a,ListNode b){
if (a == null || b == null) {
return a != null ? a : b;
}
ListNode dummy=new ListNode(-1);
ListNode pre=dummy;
ListNode la=a;
ListNode lb=b;
while(lb!=null&&la!=null){//因为接下来还需要操作la、lb所以都不能为空
if(la.val<lb.val){
pre.next=la;
pre=pre.next;
la=la.next;
}else{
pre.next=lb;
pre=pre.next;
lb=lb.next;
}
}
//这一步不要忘记!!!!!!!1
pre.next = (la != null ? la : lb);
return dummy.next;
}
}
方法二:用优先级队列
需要维护当前每个链表没有被合并的元素的最前面一个,k 个链表就最多有k 个满足这样条件的元素,每次在这些元素里面选取val 属性最小的元素合并到答案中。在选取最小元素的时候,我们可以用优先队列来优化这个过程
怎么根据Comparable方法中的compareTo方法的返回值的正负 判断升序 还是 降序?:https://www.cnblogs.com/yss818824/p/13995120.html
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
class Status implements Comparable<Status> {
int val;
ListNode p;
Status(int val, ListNode p) {
this.val = val;
this.p = p;
}
public int compareTo(Status status2) {
// 如果指定的数与参数相等返回 0。
// 如果指定的数小于参数返回 -1。
// 如果指定的数大于参数返回 1。
//如果当前值小于参数中的 则返回-1 正序输出
return this.val - status2.val;
}
}
PriorityQueue<Status> queue=new PriorityQueue<Status>();
public ListNode mergeKLists(ListNode[] lists) {
//维护当前每个链表没有被合并的元素的最前面一个,每次在这些元素里面选取val 属性最小的元素合并到答案
//遍历链表数组,把每个链表的头节点放到优先级队列
for(ListNode node:lists){
if(node!=null){
queue.offer(new Status(node.val, node));
}
}
ListNode dummy=new ListNode(-1);
ListNode pre=dummy;
while(!queue.isEmpty()){
Status f=queue.poll();
pre.next=f.p;
pre=pre.next;
//因为抽走一个了 要把同一个链表的下一个头节点也交给 优先级列表来维护
if(f.p.next!=null){
queue.offer(new Status(f.p.next.val,f.p.next));
}
}
return dummy.next;
}
}