import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类ArrayList * @return ListNode类 */ public ListNode mergeKLists(ArrayList<ListNode> lists){ if(lists.isEmpty()){ return null; } ListNode list=lists.get(0); for(int i=1;i<lists.size();i++){ ListNode list2=lists.get(i); list=mergeKLists(list,list2); } return list; } public ListNode mergeKLists (ListNode pHead1, ListNode pHead2) { ListNode pHead = new ListNode(0); ListNode temp1 = pHead; while (pHead1 != null && pHead2 != null) { if (pHead1.val <= pHead2.val) { temp1.next = pHead1; pHead1 = pHead1.next; } else { temp1.next = pHead2; pHead2 = pHead2.next; } temp1 = temp1.next; } if (pHead1 != null) { temp1.next = pHead1; } if (pHead2 != null) { temp1.next = pHead2; } return pHead.next; } }
import java.util.*;
// 类似归并排序:两两合并
public class Solution {
public ListNode mergeKLists (ArrayList<ListNode> lists) {
// write code here
while (lists.size() > 1) { // 合并至只剩1个
ArrayList<ListNode> newLists = new ArrayList<>(); // 新List
for (int i = 0; i < lists.size(); i += 2) { // 选两两合并
ListNode node1 = lists.get(i), node2 = null;
if (i + 1 < lists.size()) node2 = lists.get(i + 1);
newLists.add(merge(node1, node2));
}
lists = newLists;
}
return lists.size() == 0 ? null : lists.get(0);
}
// 合并两个升序链表
private ListNode merge(ListNode node1, ListNode node2) {
if (node1 == null) return node2;
if (node2 == null) return node1;
ListNode head = new ListNode(-1), p = head; // 表头节点
while (node1 != null && node2 != null) { // 合并
if (node1.val <= node2.val) {
p.next = node1;
node1 = node1.next;
} else {
p.next = node2;
node2 = node2.next;
}
p = p.next;
}
while (node1 != null) { // 剩余节点
p.next = node1;
node1 = node1.next;
p = p.next;
}
while (node2 != null) { // 剩余节点
p.next = node2;
node2 = node2.next;
p = p.next;
}
return head.next;
}
}
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ /** * NC51 合并k个已排序的链表 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类ArrayList * @return ListNode类 */ public ListNode mergeKLists (ArrayList<ListNode> lists) { // return solution1(lists); // return solution2(lists); return solution22(lists); // return solution3(lists); } /** * 连续归并 * @param lists * @return */ private ListNode solution1(ArrayList<ListNode> lists){ ListNode dummyHead = new ListNode(-1); for(ListNode list: lists){ dummyHead.next = merge(dummyHead.next, list); } return dummyHead.next; } /** * 合并 * 合并两个有序链表 * @param list1 * @param list2 * @return */ private ListNode merge(ListNode list1, ListNode list2){ if(list1 == null){ return list2; } if(list2 == null){ return list1; } if(list1.val <= list2.val){ list1.next = merge(list1.next, list2); return list1; }else{ list2.next = merge(list1, list2.next); return list2; } } /** * 二分归并 * @param lists * @return */ private ListNode solution2(ArrayList<ListNode> lists){ int k = lists.size(); if(k == 0){ return null; } int left,right; for(int gap=k; gap>1; gap=(gap+1)/2){ for(int i=0; i<(gap+1)/2; i++){ left = i; right = gap-i-1; if(left < right){ lists.set(left, merge(lists.get(left), lists.get(right))); lists.remove(right); } } } return lists.get(0); } /** * 递归归并 * @param lists * @return */ private ListNode solution22(ArrayList<ListNode> lists){ return divide(lists, 0, lists.size()-1); } /** * 分治: 递归 * @param lists * @param left * @param right * @return */ private ListNode divide(ArrayList<ListNode> lists, int left, int right){ if(left > right){ return null; } else if(left == right){ return lists.get(left); } int mid = left+(right-left)/2; return merge(divide(lists, left, mid), divide(lists, mid+1, right)); } /** * 堆: 优先队列 * @param lists * @return */ private ListNode solution3(ArrayList<ListNode> lists){ PriorityQueue<Integer> minHeap = new PriorityQueue<>(); for(ListNode node: lists){ while(node != null){ minHeap.offer(node.val); node = node.next; } } ListNode head = new ListNode(-1); ListNode tail = head; while(!minHeap.isEmpty()){ tail.next = new ListNode(minHeap.poll()); tail = tail.next; } return head.next; } }
import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.PriorityQueue; public class Solution2 { /* todo: 不需要头节点. */ /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * @param pHead1 ListNode类 * @param pHead2 ListNode类 * @return ListNode类 */ public ListNode Merge(ListNode pHead1, ListNode pHead2) { // 总和节点 ListNode all = new ListNode(0, null); ListNode all_index = all; // 两个指针都有值,且值不相等,比较两个值,较小的那个节点作为新链表的节点,然后指针向后移动一位 ListNode one_index = pHead1; ListNode two_index = pHead2; ListNode temp1 = null; ListNode temp = null; // 链表的到达末尾,的标志是next为null. while (one_index != null && two_index != null) { if (one_index.val < two_index.val) { temp = one_index; one_index = one_index.next; all_index.next = temp; all_index = all_index.next; } else { temp1 = two_index; two_index = two_index.next; all_index.next = temp1; all_index = all_index.next; } } if (one_index == null) { all_index.next = two_index; } else { all_index.next = one_index; } return all.next; } // write code here @Test public void test1() { Integer[] ListNodevals = {1}; Integer[] ListNodevals1 = {2}; ListNode listNode1 = headList(ListNodevals); ListNode listNode2 = headList(ListNodevals1); // 获得头和尾部分. ListNode listNode = Merge(listNode1, listNode2); // 打印 while (listNode != null) { System.out.println("listNode.val:" + listNode.val); listNode = listNode.next; } } public ListNode headList(Integer[] ListNodevals) { //头结点 ListNode head = new ListNode(); ////指针. ListNode ListNode = head; for (int i = 0; i < ListNodevals.length; i++) { // 新的节点 ListNode new_ListNode = new ListNode(ListNodevals[i], null); // 链表指针的next指向新的节点 ListNode.next = new_ListNode; ListNode = new_ListNode; } // 没有头结点. return head.next; } /** * 找到最小value变成加入到总链表或者其他结构 * 之后变动的链表1进行++ * * @param lists * @return */ public ListNode mergeKLists(ArrayList<ListNode> lists) { if (lists.size() == 0 || lists == null) { return null; } // 每个链表有链表指针和temp; PriorityQueue<Integer> pq = new PriorityQueue<>(); for (ListNode list : lists) { while (list != null) { pq.add(list.val); list = list.next; } } ListNode head_node = new ListNode(0, null); ListNode head = head_node; ListNode temp = head; while (!pq.isEmpty()) { ListNode listNode1 = new ListNode(pq.poll(), null); temp.next = listNode1; temp = temp.next; } return head.next; } @Test public void test2() { Integer[] ListNodevals = {1, 2, 3}; Integer[] ListNodevals1 = {4,5,6,7}; ListNode listNode = headList(ListNodevals); ListNode listNode1 = headList(ListNodevals1); ArrayList<ListNode> lists = new ArrayList<>(); lists.add(listNode); lists.add(listNode1); ListNode all_list = mergeKLists(lists); while (all_list != null) { System.out.println("all_list.val:" + all_list.val); all_list = all_list.next; } } }使用的是优先队列进行处理,把所有的元素扔进优先队列,之后再不断获取最小元素
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类ArrayList * @return ListNode类 */ public ListNode mergeKLists (ArrayList<ListNode> lists) { // write code here List<Integer> vals = new ArrayList<>(); for(ListNode head : lists){ while(head!=null){ vals.add(head.val); head = head.next; } } Collections.sort(vals); ListNode dummy = new ListNode(0); ListNode cur = dummy; for(Integer n : vals){ cur.next = new ListNode(n); cur=cur.next; } return dummy.next; } }暴力解法
public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类ArrayList * @return ListNode类 */ public ListNode mergeKLists (ArrayList<ListNode> lists) { if(lists.isEmpty()){ return null; } ListNode list = lists.get(0); // write code here for (int i = 1; i < lists.size(); i++) { ListNode list2 = lists.get(i); list = Marg(list,list2); } return list; } public static ListNode Marg(ListNode node1, ListNode node2) { if (node1 == null) { return node2; } if (node2 == null) { return node1; } if (node1.val <= node2.val) { node1.next = Marg(node1.next, node2); return node1; }else{ node2.next = Marg(node2.next, node1); return node2; } } }
public ListNode mergeKLists (ArrayList<ListNode> lists) { if(lists.size() == 0){ return null; } if(lists.size() == 1){ return lists.get(0); } ListNode const_head = new ListNode(0); ListNode pre = const_head; while(lists.size() > 1){ ListNode min_node = lists.get(lists.size()-1); int min_index = lists.size()-1; for(int i=lists.size()-1;i>=0;i--){ ListNode cur_node = lists.get(i); if(cur_node == null){ lists.remove(i); min_index--; }else if(min_node == null || cur_node.val < min_node.val){ min_node = cur_node; min_index = i; } } if(min_node == null) return const_head.next;; pre.next = min_node; pre = pre.next; lists.set(min_index,min_node.next); } pre.next = lists.get(0); return const_head.next; }
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类ArrayList * @return ListNode类 */ public ListNode mergeKLists (ArrayList<ListNode> lists) { // write code here // 算法时间复杂度O(NlogN),额外空间复杂度O(logN) // 分治思想,参考归并排序,K个链表可以两两合并,新合并的链表再两两合并,直到K个链表全部合并 // 这道题的重点就是把lists的划分合并区间函数的递归调用写出来 return divideMerge(lists, 0, lists.size() - 1); } // 划分合并区间函数 ListNode divideMerge(ArrayList<ListNode> lists, int left, int right) { // 递归出口 - 划分到没法再分为止 if (left > right) { return null; } else if (left == right) { return lists.get(left); } // 重点!从中间分成两段,再将合并好的两段合并 int mid = (left + right) / 2; return Merge( divideMerge(lists, left, mid), divideMerge(lists, mid + 1, right) ); } // 两个链表合并函数 - 上一道题的过程 public ListNode Merge(ListNode pHead1, ListNode pHead2) { // 算法时间复杂度O(N),额外空间复杂度O(1) // 1.处理边界情况,确保两个链表非空 if (pHead1 == null) { return pHead2; } if (pHead2 == null) { return pHead1; } // 2.找到两个有序链表头结点中较小的那个,记为targetHead,以target链表为合并的容器,另外一个链表记为source链表 ListNode targetHead; ListNode sourceHead; if (pHead1.val <= pHead2.val) { targetHead = pHead1; sourceHead = pHead2; } else { targetHead = pHead2; sourceHead = pHead1; } // 3.遍历target链表,针对每个targetCur结点,去source中尝试找到这样一个子序列: // 该子序列的所有结点满足 >= targetCur 且 < targetNext(targetCur.next) // 若能够找到,则用sourceStart和sourceEnd固定其头和尾的位置,然后将这个子序列完整纳入到target链表中 ListNode targetCur = targetHead; ListNode targetNext = targetHead.next; ListNode sourceCur = sourceHead; ListNode sourceStart = null; ListNode sourceEnd = null; while (targetCur != null) { System.out.println("targetCur: " + targetCur.val); targetNext = targetCur.next; if (sourceCur != null && sourceCur.val >= targetCur.val) { // 3.1 发现了source链表中有一个 >= targetCur的结点,先记为sourceStart // 注意!sourceStart可能已经 >= targetNext的,这种情况是不能将其纳入的,后续要对这种情况做好判断! sourceStart = sourceCur; System.out.println("发现了一个source链表中比targetCur大的结点:" + sourceStart.val); if (targetNext == null) { // 3.2 如果targetCur没有下一个结点,那么sourceStart及其后续结点必然满足要求 // 此时就会把从sourceStart开始剩余的source结点全部纳入进来,可以直接结束 System.out.println("此时target链表已经到了最后一个结点了"); targetCur.next = sourceStart; break; } // 3.3 如果targetCur还有下一个结点,那么必须找到 >= targetCur,且 < targetNext的source结点 while (sourceCur.next != null && sourceCur.next.val < targetNext.val) { // 找到source链表中一系列比targetCur大,且比targetNext小的source结点,确定它们的头和尾 // 注意!sourceCur可能本身已经 >= targetNext了,结束while循环后一定要做对应判断! sourceCur = sourceCur.next; } sourceEnd = sourceCur; // 3.4 此时存在一种可能,即只有唯一的sourceCur,确实 >= target,但是它同时 >= targetNext,此时不应该纳入,应该提前迭代 if (sourceEnd.val >= targetNext.val) { System.out.println("虽然 >= targetCur,但它同时 >= targetNext,此时也不应该放入"); targetCur = targetNext; continue; } sourceCur = sourceCur.next; // 3.5 找到了sourcr链表中满足条件的子序列,且以sourceStart开头,sourceEnd结尾,将他们整体纳入到target链表中 targetCur.next = sourceStart; sourceEnd.next = targetNext; } // 3.6 target迭代遍历 targetCur = targetNext; } return targetHead; } }
public ListNode mergeKLists (ArrayList<ListNode> lists) { // write code here if (lists == null || lists.isEmpty()) return null; Iterator<ListNode> it = lists.iterator(); ListNode res = it.next(); while (it.hasNext()) res = merge(res, it.next()); return res; } private ListNode merge(ListNode a, ListNode b) { if (a == null) return b; if (b == null) return a; if(a.val <= b.val) { a.next = merge(a.next, b); return a; } else { b.next = merge(b.next, a); return b; } }
多链表合并 import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类ArrayList * @return ListNode类 */ public ListNode mergeKLists (ArrayList<ListNode> lists) { // write code here ListNode head=new ListNode(0), cur=head, min=head; int minIdx=0; while(true){ min=null; for(int i=0;i<lists.size();++i){ if(lists.get(i)!=null){ if(min==null){ min=lists.get(i); minIdx=i; }else if(min.val>lists.get(i).val){ min=lists.get(i); minIdx=i; } } } if(min==null) break; cur.next=min; cur=min; lists.set(minIdx, min.next); } return head.next; } }
public ListNode mergeKLists(ArrayList<ListNode> lists) { PriorityQueue<ListNode> list = new PriorityQueue<>(new Comparator<ListNode>() { @Override public int compare(ListNode o1, ListNode o2) { if (o1.val < o2.val) { return -1; } else if (o1.val > o2.val) { return 1; } else { return 0; } } }); // write code here ListNode result = null; //把所有node放到优先级队列中,自动排序,最后一个node的next设置为null即可 for (ListNode listNode : lists) { if (null == listNode) { continue; } while (null != listNode) { list.add(listNode); listNode = listNode.next; } } ListNode cur = null; while (!list.isEmpty()) { if (null == result) { result = cur = list.poll(); } else { cur.next = list.poll(); cur = cur.next; } } if (null != cur) { cur.next = null; } return result; }
public ListNode mergeKLists (ArrayList<ListNode> lists) { PriorityQueue<ListNode> pq = new PriorityQueue<>((x1, x2) -> x1.val - x2.val); // pq.addAll(lists.stream().filter(x -> x != null).toList()); for (ListNode head : lists) { if (head != null) { pq.add(head); } } ListNode dummy = new ListNode(0); ListNode p = dummy; while (pq.size() > 0) { ListNode top = pq.poll(); p.next = top; top = top.next; p = p.next; if (top != null) { pq.add(top); } } return dummy.next; }
public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类ArrayList * @return ListNode类 */ public ListNode mergeKLists (ArrayList<ListNode> lists) { // write code here if(lists.size()==0||lists == null) return null; ListNode head = lists.get(0); for(int i = 1;i<lists.size();i++) { head = getNode(head,lists.get(i)); } return head; } public ListNode getNode(ListNode pHead1,ListNode pHead2) { if(pHead1==null) return pHead2; if(pHead2==null) return pHead1; ListNode sentinel = new ListNode(-1); ListNode cur = sentinel; while(pHead1!=null&&pHead2!=null) { if(pHead1.val > pHead2.val) { cur.next = pHead2; pHead2 = pHead2.next; }else{ cur.next = pHead1; pHead1 = pHead1.next; } cur = cur.next; } if(pHead1==null) cur.next = pHead2; else cur.next = pHead1; return sentinel.next; } }