万门——数据结构与算法(Python语言)学习笔记

11 篇文章 0 订阅
8 篇文章 2 订阅

数据结构与算法(Python语言)

第一章

时间复杂度

时间复杂度的简介:
  • 运行时间会随着输入的大小如何变化
  • 最好的情况: 运行时间的上限 (最少运行时间)
    • 由最简单的输入决定
    • 提供了所有输入的最终优化目标
  • 最差的情况:运行时间的下限 (最多运行时间)
    • 由最复杂的输入决定
    • 提供了所有输入的保障时间
  • 平均情况: 随机输入的运行时间的期望
    • 需要建立随机输入的模型
    • 是一种评价算法表现的方法
  • 平均情况时间通常很难测定
  • 我们通常情况下关注最差情况下的运行时间

数组

  • 盛有单一类型固定数量值的容器类

    • 以0开始的索引
    • 数组长度
    • 内存表示: 连续的
    • 边界检查
  • Python创建一维数组

题目

找到丢失的数字

现在你手上有n-1个数字,这些数字的范围是 [1 , n]
且这n-1个数字中没有重复的数字。由上述条件可知:
你手上的数字丢失了一个。请编写一段高效的找到该缺
失数字的代码。

  1. 先求和,然后减去每一个数字

  2. 异或:

    • 0^1 = 1
    • 0^0 = 0
    • 1^0 = 1
    • 1^1 = 0
    • A^A = 0
    • A^0 = A
    • 异或支持交换律

    计算机最后去做加减乘除的时候都是做的二进制。

    所以如果有n个数字,只缺失一个的话。我们可以这么做:

    1 ^ 2 ^ 3 … ^ n ^ a1 ^ a2 ^ a3 … ^ an(其中ai是我们输入的数),最后得出来的就是那个缺失的值。——因为一个数字异或本身会等于0(A ^ A=0),当所有的数字都找到对应的ai了,只有缺失的那个数字会异或0(A ^ 0=A)。

洗牌

一个好的洗牌:每一张牌出现在每一个位置的概率应该是相等的。

  • 方法一:调用random.shuffle(cards) ——如果不熟悉random欢迎点击这里查看random的用法

    import random
    def shuffle_system(cards):
        random.shuffle(cards)     
    
  • 方法二:

    • 思路:假设是a-j一共10张牌,位置分别在A-J。

      • 第一次,从A-J的地方随机取一张牌。和放在第一个位置(也就是A位置)的牌交换,如果恰好抽到的是a,那么就不交换直接到下一次
      • 第二次,从B-J的地方随机取一张牌,和放在第二个位置(也就是B位置)的牌交换。如果恰好抽到的是b,那么也就不交换直接到下一次
      • 依次类推。直到取完(9次后)。
    • 理论:为什么这样是正确的

      • 第一次,任何一张牌和第一张交换的概率是1/n。
      • 第二次,范围从1-n变成了2-n,这张牌要和第二张交换的前提必须是第一次没有抽到它且第二次抽到它。第一次没有抽到它的概率是n-1/n,第二次抽到的概率是1/n-1,相乘起来也是1/n。
      • 所以每张牌在每个位置的概率都是1/n,它是一个好的洗牌方式。
    • 代码:

    def shuffle_correct(cards):
        for i in range(len(cards)):
            randomi = i + random.randint(0, (len(cards) - i - 1))
            cards[i], cards[randomi] = cards[randomi], cards[i]
    
  • 如何证明自己的洗牌程序是对的?

    def test_shuffle(f):
        result = [[0 for i in range(10)] for j in range(10)] #产生一个十行十列的二维数组
                #第i行第j列表示第i张牌在第j列出现了几次,第一行第二列就表示第一张牌在第二个位置出现了几次
        for i in range(1000):
            A = [i for i in range(0, 10)] #生成一副0-9的牌
            f(A) #这里f是一个函数,def  test_shuffle(f),直接测试函数,A直接就赋给f这个函数了。
            '''因为调用的f都是打乱牌顺序的函数,所以f(A)调用完之后就等于已经打乱了牌的顺序了。'''
            for j in range(len(A)): 
                result[A[j]][j] += 1  # [A[j]][j]——这里的A[j]表示的是打乱顺序后,A的第j个位置是什么牌,
                                    #比如j=2 此时A[j] = 10,j=2,result[A[j]][j]=result[10][2],表示第十行第二列(即第十章牌在第二个位置出现的次数)
            
        print('\n'.join([''.join(['{:6}'.format(item) for item in row]) for row in result]))
    
数质数
判断质数

首先看一下如何判断一个数是质数 —— 除以小于它的数,只要有一个数使得余数等于0,那么就不是质数。

在判断的时候其实只要 使n被2-根号n之间的整数除(注意2-根号n是左闭右闭区间),就可判定n是否为素数。

为什么只要除到根号n呢?

根号n * 根号n = n ——也就是说一个数必定是由一个小于根号n和一个大于根号n的数相乘得到的。所以只需判断到根号n即可。

代码:

#判断一个数是否是质数
def judge_prime(n):
    i = 2  #要注意如果输入的是2,那么就直接返回True了
    while(i * i <= n):
        if n % i == 0:
            return False
        else:
            i += 1
    return True
计算小于等于n的质数个数

题目描述:给定一个正整数n,计算出小于等于n的质数有多少个。 比如17,则返回7,因为小于等于7的质数有2,3,5,7,13,17

方法一:普通方法

每个小于等于n的数都去判断一下该数是不是质数,是则count+1,最后返回count

代码:

def count_prime_one(n):
    """最普通的方法"""
    count = 0
    for i in range(2,n):
        if judge_prime(i):
            print(i,end = " ")
            count += 1
    return count
方法二:高效做法

思路:

建立一个列表,最开始把这n个数都设为True,即都是质数。

然后进行读取,是True的就划掉该数的倍数,是False的直接跳过。从2开始,2的倍数全部划掉即变为False,3的倍数也全部变为False,4已经是False了不用管,5的倍数也全部变为False,6已经是False了不用管…一直判断到根号n,为什么又是根号n?其实原理和刚刚判断质数那个差不多,这里把是True的倍数都划掉了,看图吧~

在这里插入图片描述

最后,返回是True的位置就行了

代码:

def count_prime(n):
    is_prime = [True] * (n + 1)  #为什么这里是n+1呢。因为python索引是从0开始的,这里后面等于是把下标当做了数字。大家不懂的可以自己做一遍,我一开始没懂做一遍就懂了....
    i = 2
    while (i * i <= n):
        if (is_prime[i]):
            j = i
            while (j * i <= n):
                """划到什么时候为止呢?划到i*j<=n,因为如果i*j都已经大于n了,也就不用再划了"""
                is_prime[i * j] = False
                j += 1
        i += 1
        
    count = 0
    for i in range(2, n+1):
        if (is_prime[i]):
            count += 1
            print(i, end = " ")
            
    return count

第二章:数组和动态数组

未完待续——持续更新——预计1-3天更新一章——欢迎收藏关注加点赞哦~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
数据结构与算法Python中可以通过创建新类来实现。例如,栈可以通过创建一个名为Stack的类来实现。栈的操作可以通过方法来实现,比如is_empty()用于判断栈是否为空,push(item)用于将元素压入栈中,pop()用于弹出栈顶元素,peak()用于返回栈顶元素,size()用于返回栈的大小。在Python中,可以使用列表来实现栈的功能。\[1\] 哈希表也可以在Python中实现。可以创建一个名为Hash的类,并在该类中定义相关的方法,比如__setitem__函数用于设置哈希表中的键值对。通过创建哈希表的实例对象,并调用相关的方法,可以实现对哈希表的操作。例如,可以使用H\[11\] = "tiger"来设置哈希表中键为11的值为"tiger"。\[2\] 此外,Python也提供了各种常用的排序算法的实现。例如,冒泡排序可以通过定义一个名为bubble_sort2的函数来实现。该函数可以接受一个列表作为参数,并将列表按照从大到小的顺序进行排序。在排序过程中,可以使用flag来判断列表是否已经有序,如果已经有序,则可以提前结束排序。\[3\] 因此,数据结构与算法可以通过在Python中创建新类或定义函数来实现。这些实现可以利用Python提供的强大的原生集合和方法来完成。 #### 引用[.reference_title] - *1* *2* *3* [数据结构与算法python语言实现,注释详细](https://blog.csdn.net/weixin_45702442/article/details/120026853)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值