LeetCode23.合併K個有序連結串列
阿新 • • 發佈:2020-10-05
題目描述:
給你一個連結串列陣列,每個連結串列都已經按升序排列。
請你將所有連結串列合併到一個升序連結串列中,返回合併後的連結串列。
解法一:利用堆。
將K個連結串列的頭節點放入堆中,然後依次取出,如果節點後面還有節點,就將節點繼續放入堆中。
時間複雜度:O(kn*logk),n是連結串列中的元素個數,k是連結串列個數
空間複雜度:這裡用了優先佇列,優先佇列中的元素不超過k個,故漸進空間複雜度為O(k)。
import java.util.Comparator; import java.util.PriorityQueue; public class Solution {public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length < 0){ return null; } //定義優先佇列,以及排序規則。 PriorityQueue<ListNode> queue = new PriorityQueue<>(new Comparator<ListNode>() { @Override publicint compare(ListNode o1, ListNode o2) { return (o1.val - o2.val); } }); ListNode dummyNode = new ListNode(-1); ListNode curNode = dummyNode; //把k個連結串列的第一個節點放入堆中 for (int i = 0; i < lists.length; i++){ ListNode head = lists[i];if(head != null){ queue.add(head); } } //不斷的從堆中取出節點,如果節點還有下一個節點,就把下一個節點也放入堆中。 while(!queue.isEmpty()){ ListNode node = queue.poll(); curNode.next = node; curNode = curNode.next; if(node.next != null){ queue.add(node.next); } } curNode.next = null; return dummyNode.next; } }
解法二:可以將K個連結串列逐漸縮小成規模為1的K個連結串列進行比較,最後在合併成原始規模的連結串列
時間複雜度:O(kn*logk)
空間複雜度:遞迴會使用到O(logk)空間代價的棧空間。
public class Solution2 { public ListNode mergeKLists(ListNode[] lists) { if(lists == null || lists.length == 0){ return null; } return helper(lists,0,lists.length-1); } private ListNode helper(ListNode[] lists, int left, int right) { if(left == right){ return lists[left]; } int mid = left + (right - left) / 2; ListNode l1 = helper(lists,left,mid); ListNode l2 = helper(lists,mid + 1,right); return mergeTwoLists(l1,l2); } private ListNode mergeTwoLists(ListNode l1, ListNode l2) { if(l1 == null){ return l2; } if(l2 == null){ return l1; } if(l1.val < l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; }else { l2.next = mergeTwoLists(l1,l2.next); return l2; } } }