第2章 算法基础
插入排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import random def insertion_sort1(nums): ''' :type nums: List :rtype: List ''' for j in range(1,len(nums)): key = nums[j] i = j-1 while i>=0 and nums[i] > key: nums[i+1] = nums[i] i = i - 1 nums[i+1] = key return nums def insertion_sort2(nums): ''' :type nums: List :rtype: List ''' for j in range(1,len(nums)): key = nums[j] i = j-1 while i>=0 and nums[i] < key: nums[i+1] = nums[i] i = i - 1 nums[i+1] = key return nums if __name__ == '__main__': nums = [random.randint(0,99) for _ in range(10)] print nums print insertion_sort1(nums) print insertion_sort2(nums)
|
归并排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import random def merge_sort(nums): ''' :type nums: List :rtype : List ''' if len(nums) <= 1: return nums mid = len(nums)/2 left = merge_sort(nums[:mid]) right = merge_sort(nums[mid:]) return merge(left,right) def merge(left, right): result = [] i, j = 0, 0 while i<len(left) and j<len(right): if left[i] <= right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result += left[i:] result += right[j:] return result if __name__ == '__main__': nums = [random.randint(0,99) for _ in range(10)] print nums print merge_sort(nums)
|
归并排序变形——求逆序对的数量
逆序对满足:若i < j且A[i] > A[j]
修改merge
函数即可,但下面的函数并没有对数组排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import random def count_inverse(nums): ''' :type nums: List :rtype : List ''' if len(nums) <= 1: return 0 mid = len(nums)/2 left = nums[:mid] right = nums[mid:] merge(left,right) cnt1 = count_inverse(left) cnt2 = count_inverse(right) return cnt1 + cnt2 + merge(left,right) def merge(left, right): i, j = 0, 0 count = 0 result = [] len_l = len(left) len_r = len(right) while i<len(left) and j<len(right): if left[i] <= right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 count += len_l - i result += left[i:] result += right[j:] return count if __name__ == '__main__': nums = [8, 2, 3, 6, 1, 9, 5] print nums print count_inverse(nums) print nums
|
对上面的代码进行修改后,同时可以对数组排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| def merge(left, right, nums, n): ''' :type nums: List :rtype : int ''' cnt = cnt_l = cnt_r =0 count = 0 len_l = len(left) len_r = len(right) while cnt < n: if cnt_l == len_l: while cnt < n: nums[cnt] = right[cnt_r] cnt = cnt + 1 cnt_r = cnt_r + 1 elif cnt_r == len_r: while cnt < n: nums[cnt] = left[cnt_l] cnt = cnt + 1 cnt_l = cnt_l + 1 else: if left[cnt_l] > right[cnt_r]: nums[cnt] = right[cnt_r] count = count + len_l - cnt_l cnt = cnt + 1 cnt_r = cnt_r + 1 else: nums[cnt] = left[cnt_l] cnt = cnt + 1 cnt_l = cnt_l + 1 return count def count_inverse(nums): n = len(nums) if n == 1: return 0 n1 = n/2 n2 = n - n1 left = nums[:n1] right = nums[n1:] count1 = count_inverse(left) count2 = count_inverse(right) count = count1 + count2 + merge(left, right, nums, n) return count
|