快速排序

  1. # 快排精简版
  2. def quickSort(arr, low, high):
  3. if low >= high:
  4. return
  5. l, r = low, high
  6. mid = random.randint(l, r)
  7. pivot = arr[mid] # 保存基数 ****
  8. arr[l], arr[mid] = arr[mid], arr[l] # 交换随机数到头部
  9. while l < r: # l和r 相遇时退出
  10. while l < r and pivot <= arr[r]: # 寻找第一个小于基数的坐标
  11. r -= 1
  12. arr[l] = arr[r]
  13. while l < r and pivot > arr[l]: # 寻找第一个大于基数的坐标
  14. l += 1
  15. arr[r] = arr[l]
  16. arr[l] = pivot
  17. quickSort(arr, low, l-1)
  18. quickSort(arr, l+1, high)
  19. def partion(nums, left, right):
  20. # 随机选择mid节点
  21. mid = random.randint(left, right)
  22. pivot = nums[mid]
  23. # 交换随机数到头部
  24. nums[left], nums[mid] = nums[mid], nums[left]
  25. # left和right 相遇时退出
  26. while left < right: ############ 先从右边找
  27. # 寻找第一个小于基数的坐标
  28. while left < right and pivot <= nums[right]:
  29. right -= 1
  30. nums[left] = nums[right]
  31. # 寻找第一个大于基数的坐标
  32. while left < right and pivot > nums[left]:
  33. left += 1
  34. nums[right] = nums[left]
  35. nums[left] = pivot
  36. return left
  37. def quickSort(nums, start, end):
  38. if start >= end:
  39. return
  40. mid = partion(nums, start, end)
  41. quickSort(nums, start, mid-1)
  42. quickSort(nums, mid+1, end)

快排应用:求最小的k个数

最小的k个数,利用快排提前终止,时间复杂度为On

  1. class Solution:
  2. def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
  3. def quickSort(arr, low, high):
  4. if low >= high:
  5. return
  6. l, r = low, high
  7. mid = random.randint(l, r)
  8. pivot = arr[mid] # 保存基数 ****
  9. arr[l], arr[mid] = arr[mid], arr[l] # 交换随机数到头部
  10. while l < r: # l和r 相遇时退出
  11. while l < r and pivot <= arr[r]: # 寻找第一个小于基数的坐标
  12. r -= 1
  13. arr[l] = arr[r]
  14. while l < r and pivot > arr[l]: # 寻找第一个大于基数的坐标
  15. l += 1
  16. arr[r] = arr[l]
  17. arr[l] = pivot
  18. if k<l:quickSort(arr, low, l-1)
  19. if k>l:quickSort(arr, l+1, high)
  20. return
  21. quickSort(arr,0,len(arr)-1)
  22. return arr[:k]

归并排序

  1. def mergeSort(arr):
  2. if len(arr) <= 1:
  3. return arr
  4. mid = len(arr)//2
  5. l = mergeSort(arr[:mid])
  6. r = mergeSort(arr[mid:])
  7. return merge(l, r)
  8. def merge(left, right):
  9. tmp = []
  10. l, r = 0, 0
  11. while l < len(left) and r < len(right):
  12. if left[l] <= right[r]:
  13. tmp.append(left[l])
  14. l += 1
  15. else:
  16. tmp.append(right[r])
  17. r += 1
  18. if l < len(left):
  19. tmp += left[l:]
  20. if r < len(right):
  21. tmp += right[r:]
  22. return tmp

归并的应用: 求逆序对

class Solution:
    def reversePairs(self, nums: List[int]) -> int:
        count=0
        def merge(left: list, right: list):
            l, r = 0, 0
            tmp = []
            nonlocal count
            while l < len(left) and r < len(right):
                if left[l] <= right[r]:
                    tmp.append(left[l])
                    l += 1
                else:                 
                    count+=(len(left)-l) # 只此一行
                    tmp.append(right[r])
                    r += 1
            tmp += left[l:]
            tmp += right[r:]
            return tmp

        def mergeSort(nums: list):
            if len(nums) <= 1:
                return nums
            mid = len(nums)//2
            leftL = mergeSort(nums[:mid])
            rightL = mergeSort(nums[mid:])
            return merge(leftL, rightL)


        res=mergeSort(nums)
        return count