邓心一 6 years ago
parent
commit
a9d9ce5ac4
3 changed files with 154 additions and 15 deletions
  1. 1 0
      .gitignore
  2. 138 0
      hard/23.go
  3. 15 15
      hard/25.go

+ 1 - 0
.gitignore

@@ -4,4 +4,5 @@
 node_modules
 
 *.exe
+*.bat
 

+ 138 - 0
hard/23.go

@@ -0,0 +1,138 @@
+package main
+
+// MinPQ ...
+type MinPQ []*ListNode
+
+// Insert ...
+func (pq *MinPQ) Insert(node *ListNode) {
+	*pq = append(*pq, node)
+	pq.swim(pq.Size())
+}
+
+// Min ...
+func (pq *MinPQ) Min() *ListNode {
+	return (*pq)[0]
+}
+
+// DelMin ...
+func (pq *MinPQ) DelMin() *ListNode {
+	min := (*pq)[0]
+	size := pq.Size()
+	pq.exch(1, size)
+	*pq = (*pq)[:size-1]
+	pq.sink(1)
+	return min
+}
+
+// Empty ...
+func (pq *MinPQ) Empty() bool {
+	return pq.Size() == 0
+}
+
+// Size ...
+func (pq *MinPQ) Size() int {
+	return len(*pq)
+}
+
+// Note: i, j is NOT the index of element, but the rank of it.
+func (pq *MinPQ) less(i, j int) bool {
+	return (*pq)[i-1].Val < (*pq)[j-1].Val
+}
+
+func (pq *MinPQ) exch(i, j int) {
+	(*pq)[i-1], (*pq)[j-1] = (*pq)[j-1], (*pq)[i-1]
+}
+
+func (pq *MinPQ) swim(k int) {
+	for k > 1 && pq.less(k, k/2) {
+		pq.exch(k, k/2)
+		k /= 2
+	}
+}
+
+func (pq *MinPQ) sink(k int) {
+	size := pq.Size()
+	for 2*k <= size { // !!
+		j := 2 * k
+		if j < size && pq.less(j+1, j) {
+			j++ // Compare with the less child
+		}
+		if !pq.less(j, k) {
+			break // If j !< k, ie. k <= j, break
+		}
+		pq.exch(k, j)
+		k = j
+	}
+}
+
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ *     Val int
+ *     Next *ListNode
+ * }
+ */
+func mergeKLists(lists []*ListNode) *ListNode {
+	k := len(lists)
+	if k == 0 {
+		return nil
+	}
+	dummy := ListNode{}
+	curr := &dummy
+	var pq MinPQ
+	for _, head := range lists {
+		if head != nil {
+			pq.Insert(head)
+		}
+	}
+	for !pq.Empty() {
+		min := pq.DelMin()
+		curr.Next = min
+		curr = curr.Next
+		// pq is empty, or not empty && next min != min
+		// Not empty && next min == min
+		if pq.Empty() || pq.Min().Val != min.Val {
+			if min.Next != nil {
+				pq.Insert(min.Next)
+			}
+		} else {
+			nexts := make([]*ListNode, 0, pq.Size())
+			if min.Next != nil {
+				nexts = append(nexts, min.Next)
+			}
+			for !pq.Empty() && pq.Min().Val == min.Val {
+				min = pq.DelMin()
+				curr.Next = min
+				curr = curr.Next
+				if min.Next != nil {
+					nexts = append(nexts, min.Next)
+				}
+			}
+			for _, next := range nexts {
+				pq.Insert(next)
+			}
+		}
+	}
+	return dummy.Next
+}
+
+func main() {
+	l1 := toLinkedList([]int{-9, -7, -7})
+	l2 := toLinkedList([]int{-6, -4})
+	l3 := toLinkedList([]int{-6, -5})
+	l4 := toLinkedList([]int{-9, -8, -6})
+	l5 := toLinkedList([]int{-10})
+	l6 := toLinkedList([]int{-5})
+	lists := []*ListNode{l1, l2, l3, l4, l5, l6}
+	var pq MinPQ
+	pq.Insert(&ListNode{-9, nil})
+	pq.Insert(&ListNode{-6, nil})
+	pq.Insert(&ListNode{-6, nil})
+	pq.Insert(&ListNode{-9, nil})
+	pq.Insert(&ListNode{-10, nil})
+	pq.Insert(&ListNode{-5, nil})
+	for !pq.Empty() {
+		println(pq.DelMin().Val)
+	}
+	printList(mergeKLists(lists))
+}

+ 15 - 15
hard/25.go

@@ -50,18 +50,18 @@ func reverseKGroup(head *ListNode, k int) *ListNode {
 	return head
 }
 
-func main() {
-	// 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7
-	n7 := ListNode{7, nil}
-	n6 := ListNode{6, &n7}
-	n5 := ListNode{5, &n6}
-	n4 := ListNode{4, &n5}
-	n3 := ListNode{3, &n4}
-	n2 := ListNode{2, &n3}
-	n1 := ListNode{1, &n2}
-	printList(&n1)
-	printList(reverseKGroup(&n1, 5))
-	// 0
-	n0 := ListNode{0, nil}
-	printList(reverseKGroup(&n0, 1))
-}
+// func main() {
+// 	// 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7
+// 	n7 := ListNode{7, nil}
+// 	n6 := ListNode{6, &n7}
+// 	n5 := ListNode{5, &n6}
+// 	n4 := ListNode{4, &n5}
+// 	n3 := ListNode{3, &n4}
+// 	n2 := ListNode{2, &n3}
+// 	n1 := ListNode{1, &n2}
+// 	printList(&n1)
+// 	printList(reverseKGroup(&n1, 5))
+// 	// 0
+// 	n0 := ListNode{0, nil}
+// 	printList(reverseKGroup(&n0, 1))
+// }