笔记-程序员的数学课-二进制,余数,迭代法,归纳,递归,排列组合,动态规划,树,搜索,复杂度

二进制

  1. 二进制左移一位(不溢出):数字翻倍。
  2. 二进制右移一位:
    算术右移:最高位不变,次高位补0.数字除以2并求整数商。
    逻辑右移:左边补0即可。

余数

  1. 同余定理:两个整数 a 和 b,如果它们除以正整数 m 得到的余数相等,我们就可以说 a 和 b 对于模 m 同余。
  2. 应用:分类,加密算法、MapReduce 中的数据分发、记录的高速查询和定位等等。
  3. 哈希算法:将任意长度的输入,通过哈希算法,压缩为某一固定长度的输出。(通过余数,你就能将任何数值,转换为有限范围内的一个数值,然后根据这个新的数值,来确定将数据存放在何处。例如周1-7).

迭代法

  1. 迭代:不断地用旧的变量值递推计算新的变量值。
  2. 应用:求精确值或近似值;在一定范围内查找目标;机器学习中的迭代法等(求局部解,最优解等)。
  3. 方法:确定用于迭代的变量;确定递推变量之间的关系;控制迭代过程。
  4. 要多观察问题的现象,思考其本质,看看不断更新变量值或者缩小搜索的区间范围,是否可以获得最终的解(或近似解、局部最优解),如果是,那么你就可以尝试迭代法。

归纳

归纳是我们的经验判断结果。数学归纳法是证明过程。

  1. 数学归纳法步骤:
    证明基本情况(通常是 n=1 的时候)是否成立;
    假设 n=k−1 成立, 再证明 n=k 也是成立的(k 为任意大于 1 的自然数)。
  2. 函数的递归调用模拟的就是数学归纳法的证明过程。

递归

  1. 数学归纳法简化问题
    (1)假设 n=k-1 的时候,问题已经解决(或者已经找到解)。那么只要求解 n=k 的时候,问题如何解决(或者解是多少);
    (2)初始状态,就是 n=1 的时候,问题如何解决(或者解是多少)。
  2. 小结
    递归和循环其实都是迭代法的实现,而且在某些场合下,它们的实现是可以相互转化的。
    但是,对于某些应用场景,递归确很难被循环取代。
    主要有两点原因:
    第一,递归的核心思想和数学归纳法类似,并更具有广泛性。这两者的类似之处体现在:将当前的问题化解为两部分:一个当前所采取的步骤和另一个更简单的问题。
    1. 一个当前所采取的步骤。这种步骤可能是进行一次运算(如每个棋格里的麦粒数是前一格的两倍),或者做一个选择(如选择不同面额的纸币),或者是不同类型操作的结合等等。
    2. 另一个更简单的问题。经过上述步骤之后,问题就会变得更加简单一点。这里“简单一点”,指运算的结果离目标值更近(例如赏金的总额),或者是完成了更多的选择(例如纸币的选择)。而“更简单的问题”,又可以通过嵌套调用,进一步简化和求解,直至达到结束条件。
    我们只需要保证递归编程能够体现这种将复杂问题逐步简化的思想,那么它就能帮助我们解决很多类似的问题。
    第二,递归会使用计算机的函数嵌套调用。而函数的调用本身,就可以保存很多中间状态和变量值,因此极大的方便了编程的处理。
  3. 归并排序问题(归并+分而治之)
    归并:将两个有序的序列合并成一个更大的有序序列;
    分治:将一个复杂的问题,分解成两个甚至多个规模相同或类似的子问题,然后对这些子问题再进一步细分,直到最后的子问题变得很简单,很容易就能被求解;

排列

  1. 从n个不同的元素有顺序地取出m个元素(0<=m<=n)就叫排列。当m=n时就是全排列。
  2. 排列的结果可能性计算:全排列:n!;不重复排列:n!/(n-m)!
  3. 排列常用在穷举式问题,例如暴力破解密码其实是列举出所有可能的密码一一试错。

组合

  1. 从n个元素中取出m个(0<=m<=n)就叫组合(不关心取出的顺序也不排序)。对所有m 取值的全集和的所有组合方式的列举叫做全组合。
  2. n 个元素里取出 m 个的组合,可能性数量是 (n! / (n-m)!) / m!
  3. 对于全组合而言,可能性为 2^n 种。例如,当 n=3 的时候,全组合包括了 8 种情况

动态规划

  1. 状态转移方程
    表示动态规划中从上一个状态到下一个状态之间可能存在的一些变化,以及基于这些变化的最终决策结果。我们把这样的表达式称为状态转移方程。
  2. 和排列组合等穷举的方法相比,动态规划法关注最优解。如果一个问题无需求出所有可能的解,而是要找到满足一定条件的最优解,那么可以考虑是否能使用动态规划来降低求解的工作量。
  3. 递归和状态转移的区别
    递归算法是从顶置低求解问题,而·动态规划算法是从低置顶求解问题

树的深度优先搜索

  1. 图:若图中所有的边都是有向边,这个图就是有向图。若图里所有的边都是无向边,这个图就是无向图。既含有向边,又含无向边的图,称为混合图
  2. 度:有向图中,以结点 v 为出发点的边的数量,我们叫作 v 的出度。而以 v为 终点的边之数量,称为 v 的入度
  3. 通路:结点和边的交替序列组成的就是通路。所以,通路上的任意两个结点其实就是互为连通的。如果一条通路的起始点 v1​ 和终止点 vn​ 相同,这种特殊的通路我们就叫作回路。从起始点到终止点所经过的边之数量,就是通路的长度
  4. 有向树:有向树的边都是有方向的,特点:
    (1) 有且仅有一个节点的入度为0,该节点为根;
    (2) 除根节点之外的其他节点入度都为1;
    (3) 从树根到任意节点有且只有一条通路。
  5. 二叉树:每个节点最多只有两个出度(两个子节点);应用:二叉查找树,二叉堆,二分迭代;
  6. 满二叉树:
    (1) 高度为 n(高度从 1 开始计);
    (2) 有 2^n-1 结点
    (3) 在高度为 k(0<k≤n)的这一层上,结点的数量为 2^(k-1)。
    (4) 如果把树的根标为 0,每个结点的左子结点标为 0,每个结点的右子结点标为 1,那么把根到叶子结点的所有 0 或 1 连起来,就正好对应一个二进制数。
  7. 深度优先搜索:从根节点开始,逐层向下进行搜索。
    核心思想:按照当前的通路,不断地向前进,当遇到走不通的时候就回退到上一个结点,通过另一个新的边进行尝试。如果这一个点所有的方向都走不通的时候,就继续回退。这样一次一次循环下去,直到到达目标结点。树中的每个结点,既可以表示某个子问题和它所对应的抽象状态,也可以表示某个数据结构中一部分具体的值。
  8. 观察问题是否可以使用递归的方式来逐步简化,或者是否需要像前缀树这样遍历,如果是,就可以尝试使用深度优先搜索来帮助我们思考并解决问题。
  9. 缺点:当搜索的 路中出现回路时,深度优先搜索复杂度增大,会不适用。

树的广度优先搜索

  1. 广度优先搜索:也叫宽度优先搜索,是指从图中的某个结点出发,沿着和这个点相连的边向前走,去寻找和这个点距离为 1 的所有其他点。只有当和起始点距离为 1 的所有点都被搜索完毕,才开始搜索和起始点距离为 2 的点。当所有和起始点距离为 2 的点都被搜索完了,才开始搜索和起始点距离为 3 的点,如此类推。
  2. 深度优先搜索和广度优先搜索共同点:
    (1)都不希望重复访问节点和边。在广度优先中,如果发现和某个结点直接相连的点都已经被访问过,那么下一步就会看和这个点的兄弟结点直接相连的那些点,从中看看是不是有新的点可以访问。
    (2)广度优先搜索也可以让我们访问所有和起始点相通的点,因此也被称为广度优先遍历。如果一个图包含多个互不连通的子图,那么从起始点开始的广度优先搜索只能涵盖其中一个子图。这时,我们就需要换一个还没有被访问过的起始点,继续广度优先遍历另一个子图。广度优先搜索可以使用同样的方式来遍历有多个连通子图的图,
  3. 队列实现广度优先搜索
  4. 双向广度优先搜索:从两个节点分别开始搜索,找到同在已遍历节点集中的时候。
  5. 深度优先与广度优先的区别:
    (1) 广度优先搜索,没有函数的嵌套调用和回溯操作,所以运行速度比较快。深度优先搜索的速度比较慢,而并不适合查找结点之间的最短路径这类的应用。
    (2) 广度优先需要在队列中存放新遇到的所有结点,因此占用的存储空间通常比深度优先搜索多。深度优先搜索法只保留用于回溯的结点,扩展完的结点会从栈中弹出并被删除。所以深度优先搜索占用空间相对较少。

时间和空间复杂度

  1. 通常所说的时间复杂度是指渐进时间复杂度,表示程序运行时间随着问题复杂度增加而变化的规律。
    空间复杂度是指渐进空间复杂度,表示程序所需要的存储空间随着问题复杂度增加而变化的规律。用大 O 来表示。
  2. 影响系统性能的因素:算法理论上的计算复杂度,开发实现的方案,硬件设备的规格。
  3. 复杂度分析法则

(1) 四则运算法则。如果代码是平行增加的,就是加法。如果是循环、嵌套或者函数的嵌套,那么就是乘法。

(2) 主次分明法则。主要是运用数量级和运算法则优先级的概念。省略掉低6数量级的复杂度。

(3) 齐头并进法则。主要是运用多元变量的概念,其核心思想是复杂度可能受到多个因素的影响。在这种情况下,我们要同时考虑所有因素,并在复杂度公式中体现出来。

(4) 排列组合法则。经常会用在最好、最坏和平均复杂度分析中。

(5) 图解法。二叉树图或表格。

(6) 时空互换法则。在给定的计算量下,通常时间复杂度和空间复杂度呈现数学中的反比关系。如果我们没法降低整体的计算量,那么可以通过增加空间复杂度来达到降低时间复杂度的目的,或者通过增加时间复杂度来降低空间复杂度。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值