数据结构与算法笔记(1)- 算法工具箱 (1):大O表示法,贪婪算法

模块1课程链接:Algorithmic Toolbox | Coursera

案例1:斐波拉契数列

简单算法

原理
 运行时间

当n变大时,T(n)会变得非常巨大

原因是设计到大量的重复运算(红色部分):

 

改进算法

原理

简单来说就是把“从后往前算”改进成“从前往后算”,就可以大大的减少重复运算

代码
def get_fib_number(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        prev = [0,1]
        for i in range(n-1):
            cur = prev[0] + prev[1]
            prev[0] = prev[1]
            prev[1] = cur
        return cur

 案例2:寻找最大公约数

简单算法:遍历

虽然可以解决问题,但是不够高效

改进算法:辗转相除法 

原理

如果GCD是a和b的公约数,那么他一定也是(a-b)的约数

 代码

a,b辗转相除取余数,直至某一方为0,剩下的就是最大公约数

def get_GCD(a,b):
    if a>b:
        temp = a
        a = b
        b = temp
    
    while a != 0:
        temp = a
        a = b % a
        b = temp
        
    return b

大O表示法

由案例1和2可以看出,运行时间是在优化算法的工程中的一个重要因素,但由于复杂的现实情况,准确的运行时间是不可计算的。但好处在于一些琐碎的因素可以被排除在考虑范围之外,于是在这里通过引入大O表示法(Big O Notation)来估算某一个算法的大致运行时间。

常见函数的增长率

红框内的内容是需要记忆的

计算大O表示法

定义

简单来说,大O表示法f(n)=O(g(n))中的f(n)是g(n)的等阶无穷大或者是同阶无穷大。

计算规则1:当g(n)表达成乘积的形式时,忽略常数项
 
计算规则2:当 g(n)表达成和的形式时,忽略增长较慢的项

这里参考前文:常见函数增长率中红框内的结论

这里可以搭配课堂Quiz食用,巩固以下Big O的用法

Week3 - 贪婪算法

贪婪算法 Greedy Algirithm

定义

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

贪婪算法解决问题的步骤

1. 列出当前的所有选择

2. 找到当前的最优解(Safe Choice),这个部分需要论证:为什么是最优/最安全?

3. 做出选择后,原本的问题变成一个更小的子问题

4. 对于子问题,回到步骤1,继续寻找当前最优解,直至问题解决

案例 - 找零问题

目标

现在需要用1元,5元,10元的零钱找零n元,请问我最少能用几枚硬币完成找零?

思路

1. 列出所有解:第一块硬币可以是1元,5元,10元

2. 找出当前最优解:找n元以内的最大面值硬币X (X=1或5或10)

3. 子问题:现在需要用1元,5元,10元的零钱找零(n-X)元,请问最少能用几枚硬币完成找零?

4. 继续用贪婪算法:找(n-X)元以内的最大面值硬币X (X=1或5或10),直至完成找零

(注意:这是贪婪算法的一个经典案例,但贪婪算法旨在寻找局部最优,并不能保证整体最优。事实证明这个算法有时会得出错误结论,在后续的Dynamic Programming 算法中会详细讲解)

代码
def money_change(total):
    change = 0
    coins = [10,5,1]
    for i in range(len(coins)):
        if total/coins[i] > 0:
            change += int(total/coins[i])
            total = total %  coins[i]
    return change

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值