算法图解知识点整理

二分查找:

def binary_search(list, item):
    low = 0
    high = len(list)-1
   

    while low <= high:
        mid = int((low + high)/2)
        guess = list[mid]
        if guess == item:
            return mid
        if guess < item:
            low = mid+1
        else:
            high = mid-1
    return None

my_list = [1,2,3,4,5,6,7,8]
print(binary_search(my_list, 7))

print(binary_search(my_list, 80))

选择排序:

 数组

链表

读取O(1)O(n)
插入O(n)O(1)
删除O(n)O(1)

递归:

  • 递归条件:调用自己
  • 基线条件:不再调用自己
  • 调用栈:使用方便;但存储详尽信息可能占用大量内存。
  • 栈:后进先出,压入和弹出操作
  • tips:如果使用循环,程序的性能可能更高;如果使用递归,程序可能更容易理解。

分而治之:

散列表(python字典,模拟映射关系):

  • 散列函数总是将同样的输入映射到相同的索引
  • 应用:查找(电话,IP)、防止重复(投票)、缓存
 

      散列表

(平均情况)

     散列表

(最糟情况)

数组链表
查找O(1)O(n)O(1)O(n)
插入O(1)O(n)O(n)O(1)
删除O(1)O(n)O(n)O(1)

使用散列表时,重要的时避免最糟情况,为此需要避免冲突。

  • 较低的填装因子:填装因子 = 已占用位置/总数
  • 良好的散列函数:良好的散列函数让数组中的值呈均匀分布

广度优先搜索(非加权图中查找最短路径):

  • 广度优先搜索可用于找出两种东西之间的最短距离。
  • 图:图模拟一组连接;由节点和边组成。
  • 广度优先搜索解决两类问题:
  1. 从节点A出发,有前往节点B的路吗;
  2. 从节点A出发,前往B的哪条路径最短。
  • 队列:入队;出队;先进先出。
  • 拓扑排序:若A任务依赖于B,在列表中A就必须在B后面
  • 数:一种特殊的图,其中没有往后指的边。
  • 有向图的边为箭头,箭头的方向指定了关系的方向。
  • 无向图的边不带箭头,其中关系是双向的。

找到你联系人中的芒果商:

from collections import deque


def person_is_seller(name):
    return name[-1] == 'm'

def search(name):
    search_queue = deque()
    search_queue += graph[name]
    searched = []
    while search_queue:
        person = search_queue.popleft()
        if not person in searched:
            if person_is_seller(person):
                print("The seller is: ", person)
                return True
            else:
                search_queue += graph[person]
                searched.append(person)
    return False

graph = {}
graph["you"] = ["alice", "bob", "claire"]
graph["bob"] = ["anuj", "peggy"]
graph["alice"] = ["peggy"]
graph["claire"] = ["thom", "jonny"]
graph["anuj"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []

search("you")

  • BFS 常用于找单一的最短路线,它的特点是 "搜到就是最优解"。
  • DFS 用于找所有解的问题,它的空间效率高,而且找到的不一定是最优解,必须记录并完成整个搜索,故一般情况下,深搜需要非常高效的剪枝。

狄克斯特拉算法(加权图中最快路径):

tips:仅用于有向无环图。

  1. 找出最短时间内到达的节点;
  2. 更新该节点的邻居的开销;
  3. 重复这个过程,直到对图中的每个节点都这样做了;
  4. 计算最终路径。

贝尔曼-福德算法(用于包含负权边的图)

贪婪算法(易于实现):

  • 每步都选取局部最优解,最终的得到的就是全局最优解。
  • 贪婪策略不能获得最优解,但非常接近。

集合覆盖问题

近似算法

NP完全问题:

以难解著称的问题,如旅行商问题和集合覆盖问题。(无法快速解决问题)

特点:

  • 元素较少时算法的运行速度非常快,但随着元素数量的增加,速度会变得非常慢。
  • 涉及“所有组合”的问题通常是NP完全问题。
  • 不能将问题涉及序列(如旅行商问题中的城市序列)且难以解决,它可能就是NP完全问题。
  • 如果问题涉及集合(如广播台集合)且难以解决,它可能就是NP完全问题。
  • 如果问题可转换为集合覆盖问题或旅行商问题,肯定是NP完全问题。

tips:

  • 贪婪算法寻找局部最优解,企图以这种方式获得全局最优解。
  • 对于NP完全问题,还没有找到快速解决方案。
  • 面临NP完全问题时,最佳的做法时使用近似算法。
  • 贪婪算法易于实现、运行快速快,是不错的近似算法。

动态规划:

先解决子问题,再逐步解决大问题。

仅当子问题是离散的才可使用动态规化。

K最近邻:

树:

  • 二叉查找树:不能随机访问。
 数组二叉查找树
查找O(logn)O(logn)
插入O(n)O(n)
删除O(n)O(logn)

 

  • 反向索引:常用于创建搜索引擎
  • 傅里叶变换:适用于处理信号
  • 并行算法
  • MapReduce 分布式算法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值