leetcode23_合併k個排序鏈表

題目描述:

合併 k 個排序鏈表,返回合併後的排序鏈表。請分析和描述算法的複雜度。

示例:

輸入:
[
  1->4->5,
  1->3->4,
  2->6
]
輸出: 1->1->2->3->4->4->5->6

 

思路:

1.遍歷一遍所有鏈表(O(N)),將所有元素加入到列表中,對列表排序(O(NlogN)),然後添加到一個新的鏈表(空間複雜度 O(N))返回

public static ListNode mergeKLists(ListNode[] lists) {
		List<Integer> list = new ArrayList<>();
		for (int i = 0; i < lists.length; i++) {
			ListNode node = lists[i]; // 得到每一個鏈表的頭節點
			while (node != null) {
				list.add(node.val);
				node = node.next;
			}
		}
		Collections.sort(list);
		ListNode root = new ListNode(-1);
		ListNode copy = root;
		for (Integer val : list) {
			copy.next = new ListNode(val);
			copy = copy.next;
		}
		return root.next;
	}

2.利用優先隊列,也就是小頂堆,然後每次彈出最小的,重建鏈表

/**
	 * 時間複雜度: O(Nlogk) ,其中k 是鏈表的數目
	 * 空間複雜度:
	 * O(n) 創造一個新的鏈表需要 O(n)
	 * @param lists
	 * @return
	 */
	public static ListNode mergeKLists2(ListNode[] lists) {
        if (lists == null || lists.length == 0) {
			return null;
		}

		ListNode head = new ListNode(0);
                //優先隊列--->也就是小頂堆
		PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
		for (ListNode node : lists) {
			while (node != null) {
				pq.add(node.val);
                node = node.next;
			}
		}
		ListNode curr = head;
		while (!pq.isEmpty()) {   //每次彈出來最小的
			curr.next = new ListNode(pq.poll());
			curr = curr.next;
		}
		return head.next;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章