力扣困难题 23. 合并 K 个升序链表

83 阅读1分钟

这道题是合并有序链表数组,这道题虽然是困难题但是,是十分简单的我们只需要写一个合并链表的方法然后遍历合并即可

遍历合并,将每一个list[i] (i > 0)都与list[0]进行合并,最后返回结果

func mergeKLists(lists []*ListNode) *ListNode {
	if len(lists) == 0 {
		return nil
	}
	res := lists[0]
	for i := 1; i < len(lists); i++ {
		res =  merge(res, lists[i])
	}
	return res
}

func merge(l1, l2 *ListNode) *ListNode {
	head := &ListNode{}
	tail := head
	for l1 != nil && l2 != nil {
		if l1.Val < l2.Val {
			tail.Next = l1
			l1 = l1.Next
			tail = tail.Next
		} else {
			tail.Next = l2
			l2 = l2.Next
			tail = tail.Next
		}
	}
	if l1 != nil {
		tail.Next = l1
		l1 = l1.Next
		tail = tail.Next
	}
	if l2 != nil {
		tail.Next = l2
		l2 = l2.Next
		tail = tail.Next
	}
	return head.Next
}

分治优化,让每一个数组两两进行合并

image.png 就是这种效果能让两个链表的长度合并的时候尽量相等优化一点时间

func mergeKLists(lists []*ListNode) *ListNode {
   return merge(lists, 0, len(lists) - 1)
}
func merge(list []*ListNode, l, r int) *ListNode {
   if l > r {
      return nil
   }
   if l == r {
      return list[l]
   }
   mid := (l + r) >> 1
   return mergeTwoList(merge(list, l, mid), merge(list, mid+1, r))
}

func mergeTwoList(l1, l2 *ListNode) *ListNode {
   head := &ListNode{}
   tail := head
   for l1 != nil && l2 != nil {
      if l1.Val < l2.Val {
         tail.Next = l1
         l1 = l1.Next
         tail = tail.Next
      } else {
         tail.Next = l2
         l2 = l2.Next
         tail = tail.Next
      }
   }
   if l1 != nil {
      tail.Next = l1
      l1 = l1.Next
      tail = tail.Next
   }
   if l2 != nil {
      tail.Next = l2
      l2 = l2.Next
      tail = tail.Next
   }
   return head.Next
}