python百题大通关解题记录-排序算法

目录

045实现选择排序

挑战内容

046实现插入排序

挑战内容

047实现快速排序 

挑战内容

048实现归并排序 

挑战内容

049实现基数排序 

挑战内容

050对字符串数组进行排序 

挑战内容

051在旋转排序数组中查找元素 

挑战内容

052在排序矩阵中查找元素

挑战内容

 053合并排序数组

挑战内容


内容编译自 Donne Martin 的开源项目

045实现选择排序

实现选择排序算法。介绍如下:

  • 选择排序的工作原理是每一次从需要排序的数据元素中选出最小的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排列完毕。

挑战内容

本次挑战中,你需要在 selection_sort.py 文件中补充类 SelectionSort 的空缺部分。

  • SelectionSort 中的 sort 方法用于进行选择排序。
  • sort 函数的参数 data 用于指定需要排序的数据,其中数据为数组格式。
  • sort 函数需要返回排序后的数据。
  • 如果传入的 data 为 None,需要使用 raise 语句显示 TypeError
  • 如果传入的 data 为空数组,需要返回空数组。

 代码:

class SelectionSort(object):

    def sort(self, data):
        if data is None:
            raise TypeError
        if len(data)<2://空数组和只有一个元素的数组
            return data
        for i in range(len(data)-1)://找到剩下元素中的最小元素,并和当前元素交换交换
            min_index=i
            for j in range(i+1,len(data)):
                if data[j]<data[min_index]:
                    min_index=j
            if data[min_index]<data[i]:
                data[i],data[min_index]=data[min_index],data[i]
        return data

046实现插入排序

实现插入排序算法。介绍如下:

  • 插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从前向后扫描,找到相应位置并插入。

挑战内容

本次挑战中,你需要在 insertion_sort.py 文件中补充类 InsertionSort 的空缺部分。

  • InsertionSort 中的 sort 方法用于进行插入排序。
  • sort 函数的参数 data 用于指定需要排序的数据,其中数据为数组格式。
  • sort 函数需要返回排序后的数据。
  • 如果传入的 data 为 None,需要使用 raise 语句显示 TypeError
  • 如果传入的 data 为空数组,需要返回空数组。

 代码:

class InsertionSort(object):

    def sort(self, data):
        if data is None:
            raise TypeError
        if len(data)<2:
            return data
        for r in range(1,len(data)):
            for l in range(r):
                if data[r]<data[l]:
                    temp=data[r]
                    data[l+1:r+1]=data[l:r]
                    data[l]=temp
        return data

047实现快速排序 

实现快速排序算法。介绍如下:

  • 快速排序的工作原理是通过一次排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。

挑战内容

本次挑战中,你需要在 quick_sort.py 文件中补充类 QuickSort 的空缺部分。

  • QuickSort 中的 sort 方法用于进行快速排序。
  • sort 函数的参数 data 用于指定需要排序的数据,其中数据为数组格式。
  • sort 函数需要返回排序后的数据。
  • 如果传入的 data 为 None,需要使用 raise 语句显示 TypeError
  • 如果传入的 data 为空数组,需要返回空数组。

代码: 

class QuickSort(object):

    def sort(self, data):
        if data is None:
            raise TypeError
        return self._sort(data)

    def _sort(self,data):
        if len(data)<2:
            return data
        equal=[]
        left=[]
        right=[]
        pivot_index=len(data)//2
        pivot_value=data[pivot_index]
        for item in data:
            if item==pivot_value:
                equal.append(item)
            elif item<pivot_value:
                left.append(item)
            else:
                right.append(item)
        left_=self._sort(left)
        right_=self._sort(right)
        return left_+equal+right_

048实现归并排序 

实现归并排序算法。归并排序的介绍如下:

  • 将待排序的线数据不断地切分成若干个部分,直到每个部分只包含一个元素,这时,可以认为只包含一个元素的序列是有序的。
  • 将切分后的数据两两合并,每合并一次,就会产生一个新的且更长的有序序列,重复这一步骤,直到最后只剩下一个序列,这个序列就是排好序的数据。

挑战内容

本次挑战中,你需要在 merge_sort.py 文件中补充类 MergeSort 的空缺部分。

  • MergeSort 中的 sort 方法用于进行归并排序。
  • sort 函数的参数 data 用于指定需要排序的数据,其中数据为数组格式。
  • sort 函数需要返回排序后的数据。
  • 如果传入的 data 为 None,需要使用 raise 语句显示 TypeError
  • 如果传入的 data 为空数组,需要返回空数组。

代码:划分并递归排序

class MergeSort(object):

    def sort(self, data):
        if data is None:
            raise TypeError
        return self._sort(data)

    def _sort(self,data)://逐次划分data,并逐层返回排序结果
        if len(data)<2:
            return data
        mid=len(data)//2
        left=data[:mid]
        right=data[mid:]
        left=self._sort(left)//左排序结果
        right=self._sort(right)//右排序结果
        return self._merge(left,right)//对左右排序的结果

    def _merge(self,left,right)://左右堆排序,剩下的元素直接加入result
        l=0
        r=0
        result=[]
        while l<len(left) and r<len(right):
            if left[l]<right[r]:
                result.append(left[l])
                l+=1
            else:
                result.append(right[r])
                r+=1
        while r<len(right):
            result.append(right[r])
            r+=1
        while l<len(left):
            result.append(left[l])
            l+=1
        return result

049实现基数排序 

实现基数排序算法。基数排序的介绍如下:

  • 将整数按位数切割,然后将数值统一为同样的数位长度,数位较短的数前面补零。
  • 从最低位开始,依次进行一次排序。
  • 从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

挑战内容

本次挑战中,你需要在 radix_sort.py 文件中补充类 RadixSort 的空缺部分。

  • RadixSort 中的 sort 方法用于进行基数排序。
  • sort 函数的参数 array 用于指定需要排序的数据,其中数据为数组格式。
  • sort 函数的参数 base 用于指定数据的进制,默认为十进制。
  • sort 函数需要返回排序后的数据。
  • 如果传入的 array 为 None,需要使用 raise 语句显示 TypeError
  • 如果传入的 array 为空数组,需要返回空数组。

代码:

class RadixSort(object):

    def sort(self, array, base=10):
        if array is None:
            raise TypeError
        if len(array)<2:
            return array
#求数据元素最大位数
        max_element=max(array)
        max_digits=len(str(abs(max_element)))
        curr_array=array
#每位数字循环一次
        for digit in range(max_digits):
            buckets=[[] for _ in range(base)]//创建基数存储列表
            for item in curr_array:
                buckets[(item//(base**digit))%base].append(item)//根据基数存储数据
            curr_array=[]
            for bucket in buckets://取出基数数据,重新放入列表curr_array
                curr_array.extend(bucket)
        return curr_array

050对字符串数组进行排序 

实现一个算法对字符串数组按照字母顺序进行排序,并使变位词挨在一起。变位词的介绍如下:

  • 变位词指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母所出现的次数都是相同的。例如 “unclear” 和 “nuclear”、 “rimon” 和 “minor” 都是变位词。

挑战内容

本次挑战中,你需要在 anagrams.py 文件中补充类 Anagram 的空缺部分。

  • Anagram 中的 group_anagrams 方法用于对字符串数组进行排序,并使变位词挨在一起。
  • group_anagrams 函数的参数 items 用于指定需要排序的数组,数组的元素为字符串。
  • group_anagrams 函数需要返回排序后的数组。
  • 如果传入的 items 为 None,需要使用 raise 语句显示 TypeError
  • 可以调用有序字典 OrderedDict 帮助排序。

代码:有序字典存入的键值对有顺序,把排序

from collections import OrderedDict


class Anagram(object):

    def group_anagrams(self, items):
        if items is None:
            raise TypeError
        if not items:
            return items
        anagram_map=OrderedDict()//有序字典:键为排好序的字符串生成的元组(只有转换成元组才能当键),值为存储原始数据的列表
        for item in items:
            sorted_chars=tuple(sorted(item))
            if sorted_chars in anagram_map:
                anagram_map[sorted_chars].append(item)
            else:
                anagram_map[sorted_chars]=[item]
        result=[]
        for value in anagram_map.values():
            result.extend(value)
        return result

051在旋转排序数组中查找元素 

实现一个算法在旋转排序数组中查找元素。介绍如下:

  • 旋转排序数组是指,某个按照升序排序的数组在预先未知的某个点上进行了旋转。例如 [10, 12, 14, 1, 1, 3, 5, 6, 7, 8] 是一个旋转排序数组。
  • 需要借鉴二查找法。二分查找法是从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中继续使用二分查找,直到找到所查找的元素。

挑战内容

本次挑战中,你需要在 search_array.py 文件中补充类 Array 的空缺部分。

  • Array 中的 search_sorted_array 方法用于在旋转排序数组中查找元素。
  • search_sorted_array 函数的参数 array 用于指定传入的旋转排序数组。
  • search_sorted_array 函数的参数 val 用于指定要查找的元素。
  • search_sorted_array 函数需要返回要查找元素的索引值。
  • 如果传入的 array 或者 val 为 None,需要使用 raise 语句显示 TypeError
  • 如果要查找的元素不在数组中,则返回 None

 原理如下图 

代码:

from re import A
from unittest import result


class Array(object):

    def search_sorted_array(self, array, val):
        if array is None or val is None:
            raise TypeError
        if not array:
            return None
        return self._search_sorted_array(array,val,start=0,end=len(array)-1)

    def _search_sorted_array(self,array,val,start,end):
        if end<start:
            return None
        mid=(start+end)//2
        if array[mid]==val://如果正好相等,返回索引;否则进入以start为标准的判断
            return mid
        if array[start]<array[mid]://mid在上升段
            if array[start]<=val<=array[mid]:
                return self._search_sorted_array(array,val,start,mid-1)
            else:
                return self._search_sorted_array(array,val,mid+1,end)
        elif array[start]>array[mid]://mid在下降段
            if array[mid]<val<=array[end]:
                return self._search_sorted_array(array,val,mid+1,end)
            else:
                return self._search_sorted_array(array,val,start,mid-1)
        else://mid在水平段,需要判断是在开始的start段还是在结束的end段
            if array[mid]!=array[end]:
                return self._search_sorted_array(array, val, mid + 1, end)
            else:
                result=self._search_sorted_array(array, val, start, mid - 1)
                if result!=None:
                    return result
                else:
                    return self._search_sorted_array(array,val,mid+1,end)

052在排序矩阵中查找元素

实现一个算法在排序矩阵中查找元素。介绍如下:

  • 排序矩阵是指行和列都是有序的矩阵。对于矩阵中的每一个元素,同一行左面/同一列上面所有的元素都小于等于它,同一行右面/同一列下面所有的元素都大于等于它

挑战内容

本次挑战中,你需要在 search_matrix.py 文件中补充类 SortedMatrix 的空缺部分。

  • SortedMatrix 中的 find_val 方法用于在排序矩阵中查找元素。
  • find_val 函数的参数 matrix 用于指定传入的排序矩阵。
  • find_val 函数的参数 val 用于指定要查找的元素。
  • find_val 函数需要返回要查找元素的索引值,格式为 (row, col)
  • 如果传入的 matrix 或者 val 为 None,需要使用 raise 语句显示 TypeError
  • 如果要查找的元素不在矩阵中,则返回 None

 窍门:以变化趋势上的对角线两端端点为起始点,进行行列调整

 代码:

class SortedMatrix(object):

    def find_val(self, matrix, val):
        if matrix is None or val is None:
            raise TypeError
        row=0
        col=len(matrix)-1//从顶点开始,类似于二查找法的从中点开始
        while row<len(matrix) and col>=0:
            if matrix[row][col]==val:
                return (row,col)
            elif matrix[row][col]>val:
                col-=1
            else:
                row+=1
        return None

 053合并排序数组

给定排序数组 A 和 B,实现一个算法将 B 按排序顺序合并到 A 中。介绍如下:

  • 数组 A 和 B 的均为排序数组,数字按从小到大排列。
  • 数组 A 的的长度为 n,其中前 m 个为数字,后 n-m 个为 None;数组 B 的长度为 n-m
  • 需要将数组 B 的数字依次添加到数组 A 中,添加元素后 A 的依旧是排序数组。

挑战内容

本次挑战中,你需要在 merge_array.py 文件中补充类 Array 的空缺部分。

  • Array 中的 merge_into 方法用于合并排序数组。
  • merge_into 函数的参数 source 和 dest 用于指定传入的数组 A 和 B
  • merge_into 函数的参数 source_end_index 和 dest_end_index 用于指定传入的数组 A 和 B 的长度,其中 A 的长度是指有数字的长度。
  • merge_into 函数需要返回合并后的 A
  • 如果传入的 source 或者 dest 为 None,需要使用 raise 语句显示 TypeError
  • 如果传入的 source_end_index 或者 dest_end_index 小于 0,需要使用 raise 语句显示 ValueError

代码:

class Array(object):

    def merge_into(self, source, dest, source_end_index, dest_end_index):
        if source is None or dest is None:
            raise TypeError
        if source_end_index<0 or dest_end_index<0:
            raise ValueError
        if not source:
            return dest
        if not dest:
            return source
        source_index=source_end_index-1//从最大索引开始倒退,避免前方元素的频繁移动
        dest_index=dest_end_index-1//从最大索引开始倒退
        insert_index=source_end_index+dest_end_index-1
        while dest_index>=0:
            if source[source_index]>dest[dest_index]:
                source[insert_index]=source[source_index]
                source_index-=1
            else:
                source[insert_index]=dest[dest_index]
                dest_index-=1
            insert_index-=1
        return source

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值