python数据结构&算法个人学习笔记

参考视频课

目录

1.查找

        线性查找:

        二分查找:是否需要先排序?

2.排序

        冒泡排序:

        选择排序

        快速排序——双指针排序

3.贪心算法:最优问题

        背包问题

        数字拼接问题

        活动选择问题

 4.动态规划:自问题的重复计算

        钢条切割问题:

        最长公共子序列:


递归两个特点:调用自身;结束条件

e.g:运行的结果是打印1 2 3

def fun(x):
    if x>0:
        fun(x-1)
        print(x)
fun(3)

1.查找

        线性查找:

def linear_search(li,val):
    for ind, v in enumerate(li):
        if v == val:
            return ind
    return None
li = [3,2,6,1,5]

print(linear_search(li,6)) 

        二分查找:是否需要先排序?

def binary_search(li, val):
    left = 0
    right = len(li) - 1
    while left <= right:  # 说明候选区有值
        mid = (left + right) // 2
        if li[mid] == val:
            return mid
        elif li[mid] > val:  # 待查找的值在mid左侧
            right = mid - 1
        else:
            left = mid + 1
    else:
        return None

2.排序

常见排序方法
排序low B三人组 排序NB三人组 其他
冒泡排序 快速排序 希尔排序
选择排序 堆排序 计数排序
插入排序 归并排序 基数排序

        冒泡排序:

#复杂度:O(n2)
def bubble_sort(li):
    for i in range(len(li)-1):     #第i趟
        for j in range(len(li)-i-1):
            if li[j] > li[j+1]:
                li[j],li[j+1] = li[j+1],li[j]
#改进的冒泡
def bubble_sort2(li):
    for i in range(len(li)-1):     #第i趟
        exchange = False
        for j in range(len(li)-i-1):
            if li[j] > li[j+1]:
                li[j],li[j+1] = li[j+1],li[j]
                exchange = True
        print(li)
        if not exchange:    #如果第i趟没有发生交换,就退出排序,提高效率
            return

        选择排序

def select_sort(li):
    for i in range(len(li)):
        for j in range(i,len(li)):
            if li[i] > li[j]:
                li[i],li[j] = li[j],li[i]

        快速排序——双指针排序

def partition(li, left, right):
    tmp = li[left]  # 把左侧的值先保存
    while left < right:  # 必须加这个while条件
        while left < right and li[right] >= tmp:  # 从右开始比较,不比临时值小,就将下标左移
            right -= 1
        li[left] = li[right]

        while left < right and li[left] <= tmp:  # 从左向右比较
            left += 1
        li[right] = li[left]
    li[left] = tmp
    return left


def quick_sort(li, left, right):
    if left < right:
        mid = partition(li, left, right)
        quick_sort(li, left, mid - 1)
        quick_sort(li, mid + 1, right)


li = [1, 2, 4, 3, 5, 6, 7, 9, 8]
quick_sort(li, 0, len(li) - 1)
print(li)

3.贪心算法:最优问题

        背包问题

                求单位重量价格最大的

        数字拼接问题

li = [32, 94, 128, 1286, 6, 71]
li1= [128,1286]
li2= [728,7286]

def number_join(li):
    li = list(map(str, li))
    for i in range(len(li)):
        for j in range(i + 1, len(li)):
            if li[i] + li[j] < li[j] + li[i]:
                li[i], li[j] = li[j], li[i]
    return ''.join(li)

print(number_join(li2))

        活动选择问题

activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11), (8, 12), (2, 14), (12, 16)]

activities.sort(key=lambda x: x[1])


def activity_selection(a):
    res = [a[0]]
    for i in range(1, len(a)):
        if a[i][0] >= res[-1][1]:  # 当前活动开始时间大雨等于最后一个入选活动的结束时间,保证不冲突
            res.append(a[i])
    return res


print(activity_selection(activities))

 4.动态规划:自问题的重复计算

        钢条切割问题:

                        n个切割点,每个点可以选择切/不切,一共2**(n-1)种切割方法

p = [0,1,5,8,9,10,17,17,20,24,30]   #0用来占位


def cut_rod_recurision(p,n):  #n:钢条长度
    if n == 0:
        return 0
    else:
        res = 0
        for i in range(1,n+1):
            res = max(res,p[i] + cut_rod_recurision(p,n-i))    #在钢条不切割(res)、左边i个不切割右边切割之间区最大值
        return res


print(cut_rod_recurision(p,9))

        最长公共子序列:

                        应用场景——字符串相似度比对、模糊搜索 

def lcs_length(x,y):
    m = len(x)
    n = len(y)
    c = [[0] * (n+1)] * (m+1)
    for i in range(1,m+1):
        for j in range(1,n+1):
            if x[i-1] == y[j-1]:
                c[i][j] = c[i-1][j-1] + 1
            else:
                 c[i][j] = max(c[i-1][j],c[i][j-1])
    return c[m][n]

print(lcs_length("ABCBDAB","BDCABA"))

2月26日  

面向对象(一种设计模式) 

        三个特点:封装;继承;多态(python本身就是多态的,无需care,c++ java会有虚函数可以了解多态)

        接口:若干抽象方法的集合; 类就属于是接口

        SOLID原则:(5个英文首字母)

                        开放封闭原则:模块和函数对扩展开放,对修改关闭。  尽量不修改原有代码下进行扩展

                        里氏替换原则:引用父类的地方必须能使用子类对象

                        依赖倒置原则:没听懂

                        接口隔离原则:不要使用单一的总接口,使用多个专门的接口,客户端不应该依赖那些他不需要的接口

                        单一指责原则:不要存在多于一个导致类变更的原因,一个类只负责一个事情

        设计模式分类:

                       创建型模式:(1)简单工厂模式——通过一个工厂类负责创建产品类的实例,隐藏类内部实现

                                            (2)工厂方法模式——

                                            (3)抽象工厂模式——定义一个工厂类,让工厂子类来创建一系列相关或相互依赖的对象

                       结构型模式:

                       行为型模式: 

你可能感兴趣的:(数据结构,算法,python)