[刷题] MergeSort

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/programmingfool5/article/details/82954000

题目1️⃣:

数组中的逆序对数.

思路:

利用归并排序的思想.

  1. 首先将数组分为两两组合, 再对两两组合排序, 排序的过程中记录是不是逆序对数.
  2. 然后再对这些组合排序, 在排序的过程中, 再对左右两边的子串进行逆序的计数.然后再对这些组合排序, 在排序的过程中, 再对左右两边的子串进行逆序的计数.
  3. 采用递归, 终止条件肯定是字符串的字数小于2.
  4. 每次对字符串分两组递归. 计数的条件是当前面的数组的元素大于后面数组的元素时, 这时计数累积的是前面数组的未排序元素的个数.
  5. O(nlogn)
count = 0
def MergeSort(nums):
	global count
	if nums <= 1 :
		return nums
	mid = len(nums) // 2
	left = MergeSort(nums[:mid])
	right = MergeSort(nums[mid:])
	l, r =0
	result = []
	while l < len(left) and r < len(right):
		if left[l] <= right[r]:
			result.append(left[l])
			l += 1
		else:
			reslut.append(right[r])
			r += 1
			count += len(left) - l
	result += left[l:]
	result += right[r:]
	return  result
			

题目2️⃣:

合并n个有序链表

思路:

也可以用分治的思想, 将n个有序链表两两合并. 不过时间复杂度很高, 另一种方法是使用堆来做.

def MergeKlists(lists):

	if not lists:
		return None
	if len(lists) == 1:
		return lists[0]
	if len(lists) == 2:
		return MergeTwo(lists[0], lists[1])
	mid = len(lists) // 2
	left = mergeKlists(lists[:mid])
	right = mergetKlists(lists[mid:])
	
	return mergeTwo(left,right)
	
def MergeTwo(l1,l2):
	dummy  = ListNode(0)
	pre = dummy
	while l1 and l2:
		if l1.val < l2.val:
			pre.next = l1
			l1 = l1.next
		else:
			pre.next = l2
			l2 = l2.next
		pre = pre.next
	pre.next = ll if l1 else l2
	return dummy.next

堆的方法:

import heapq
def mergeLists(lists):
	if not lists:
		return None
	heap = []
	for node in lists:
		if node:
			heapq.heappush(heap,(node.val, node))
		dummy = pre = ListNode(-1)
		while heap:
			_, cur = heapq.heappop(heap)
			if cur.next:
				heapq.heappush(heap,(cur.val,cur)
			pre.next = cur
			pre = cur
	return dummy.next

猜你喜欢

转载自blog.csdn.net/programmingfool5/article/details/82954000