题目1️⃣:
数组中的逆序对数.
思路:
利用归并排序的思想.
- 首先将数组分为两两组合, 再对两两组合排序, 排序的过程中记录是不是逆序对数.
- 然后再对这些组合排序, 在排序的过程中, 再对左右两边的子串进行逆序的计数.然后再对这些组合排序, 在排序的过程中, 再对左右两边的子串进行逆序的计数.
- 采用递归, 终止条件肯定是字符串的字数小于2.
- 每次对字符串分两组递归. 计数的条件是当前面的数组的元素大于后面数组的元素时, 这时计数累积的是前面数组的未排序元素的个数.
- 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