算法设计与分析
书海漫舟
当你的实力不足以支撑自己的野心的时候,所谓的野心也就不足为道了
展开
-
算法设计与分析——最优二叉树问题
/* 用 r 来表示根节点搜索二叉树 用 small 来表示查找的平均概率 */#include <iostream>using namespace std;struct Node{ double small; int r;};int main(){ /* 对角线为本身概率 由于是搜索树,左下角矩阵为 0 p[i][j] = min(k=i-j) 平均概率和 + 本身 状态转移方程 pn = min(k = i - j) p[i][k -原创 2021-05-19 10:03:05 · 731 阅读 · 0 评论 -
算法设计与分析——矩阵链乘积问题
#include <iostream>#include <vector>using namespace std;struct Node{ int small; int r;};// 打印加括号方式 void get(Node ** target, int i, int j, vector<char>& a){ if(i == j) { a.push_back('A'); a.push_back('0' + i); retu原创 2021-05-18 21:05:20 · 759 阅读 · 0 评论 -
算法设计与分析——最长子序列问题
给定两个字符串,求解两个字符串的最长子序列(不是最长子串) 如果采用暴力解法的话,对于两个长分别为 m、n 的字符串来说,各有 2 ^ n 个子串如果需要两两比较的话,会有 2 ^ (m + n) 次比较,每一次比较中又会有很多的工作量,所以,不可取 采用DP的方法: 对于两个串 *****a *****b 如果 a 和 b 相等,那么就可以将问题转化为求前面的最长子序列然后拼接上最 后的a,如果 a 和 b 不等,那么就可以将其中一个去掉,求剩下两个串的最长 子序列,于原创 2021-04-28 19:03:02 · 291 阅读 · 0 评论 -
算法设计与分析——动态规划
动态规划什么时候用呢?类似于这种 可以发现,当计算 f(n) 的时候,需要用到 f(n 2 1),当计算 f(n - 1) 的时候,还是需要用到 f(n - 2),这样,一个子问题就要计算 k 次,显然增加了时间复杂度,这种时候就需要用到动态规划了,将所有的子问题都用一个数组记录下来,避免重复计算,可以说,动态规划的精髓就在于数组记录状态和状态转移方程。DP:1、分析子问题的依赖关系(子问题:重叠) 2、采用自底向上的方法依次求解 3、从最小规模求解,一直到最大子问题 注:子问题不管原创 2021-04-28 18:47:09 · 277 阅读 · 0 评论 -
算法设计与分析——第K小问题
这个问题就是求无序数组中的第K小的问题方法一:直接冒泡K次,第一次得到第一小的,第K次得到第K小的方法二:对数组进行预排序方法三:二分快查方法四:分组二分快查注:这里的代码只经过自己构造的数据检验,如果有误,敬请谅解!!!方法一:直接冒泡K次 对于这个算法,可以发现,当数组规模为 n 时,如果要求的是第 1 小或者是第 n 小(第1大)那么问题相对来说会简单一点,因为只要进行一次冒泡就行了,但是当求第 n / 2 的问题时,相对而言工作量会是最大的,而对于第 k 小,如果第 n - k原创 2021-04-28 17:16:13 · 839 阅读 · 0 评论 -
算法设计与分析——快速排序
对于快速排序,有原地分区算法和双指针算法,这里采用的是原地分区算法,两种算法略有不同,但是其核心思想都是一样的,将小于的放到左边,大于的放到右边。 原地分区算法:每一次维护一个中轴,这个中轴左边的是比目标值小的,右边的是比目标值大的,每一次只要将小于的移动到中轴左边,并将中轴++,最后得到的就是目标序列了 双指针法:双指针法用两个指针指向数组的头和尾,将头部的值保存起来,然后从后面开始,找到第一个小于头值的元素,替换头指针指向的元素,这时尾指针所在位置就会 “空缺” 出一个位置,这时移动.原创 2021-04-25 20:23:15 · 401 阅读 · 0 评论 -
算法设计与分析——矩阵乘法和归并排序
一、矩阵乘法 传统的矩阵乘法是按照矩阵乘法的公式来做,现在我们试着用分治的思想来做,先将原来的矩阵分成大小相等的四份,如图所以,新得到的矩阵应该是这个样子所以对于矩阵分开的乘法,时间复杂度应该是这样的(只计算乘法)所以,可以得到 T(n) = 8 * T(n / 2) = — = 8 ^ i * T(n / (2 ^ i))当 i = log n 时,T(n) = n ^log(8) = n ^ 3所以 T(n) = O(n ^ 3)二、归并排序void merge(int * a原创 2021-04-25 19:17:51 · 387 阅读 · 0 评论 -
算法设计与分析——递归
一、普遍意义上的递归二、斐波那契数列的三变量低估四、记忆递归原创 2021-04-13 14:59:47 · 199 阅读 · 0 评论 -
算法设计与分析——分而治之,归并
归并排序的思想主要在于 “分” 和 “治”,如何将一个大问题分成若干小问题,如何对于每个小问题继续“分而治之”,最终由得到的若干小问题的解归并得到最终的答案 从上面的描述你会发现,分治策略可以写成一个递归函数,那么分治策略到底好不好呢?我们以找最大值来说 当找一组数据的最大值的时候,用传统的比较方式,先设立一个最大值,然后通过遍历来找到这个最大值,这样比较一共要比较 n - 1 次,而如果采用分治的策略,我不去一个一个的比较,而是先将样本分成若干部分,从每一个部分得到最大值,然后再对这一组最.原创 2021-03-29 18:13:02 · 207 阅读 · 0 评论 -
算法设计与分析——算法设计要求
一、非递归程序(往往以迭代为基础)(1) 确定哪些参数作为输入量的规模(2) 找出算法的基本操作(主要操作)(作为规律,往往位于最内层循环)(3) 检查基本操作的执行次数是否只依赖于输入规模,若不是,考虑最坏,最好,平均(4) 建立一个基本操作执行次数的求和公式(5) 利用求和公式建立闭合公式 或者 至少决定他的增长次数1、求和公式:类似于 n + (n - 1) + --- + 2 + 1 闭合公式:类似于 n(n + 1) / 2二、递归程序...原创 2021-03-31 10:20:10 · 563 阅读 · 0 评论 -
算法设计与分析——算法概论
这片文章主要是对概念的阐述记录算法:解决问题的方法,是一种解决问题的清晰的指令,即:对某个问题,在一定规模的输入,在有限的时间之内, 获得符合要求的输出算法特点: 1、有 >= 0 个输入 2、有 >= 1 个输出 3、算法指令清晰,无歧义 4、算法中的每条指令的执行次数和时间都是有限的程序:算法的语言实现,可以是死循环,而算法必须是清晰的、有限的,所以算法不能是死循环算法表示: 1、自然语言(汉字描述) 2、计算机语言:c++, c, java --- 3、类原创 2021-03-26 10:10:01 · 295 阅读 · 0 评论 -
算法设计与分析——常见的复杂度
思考:lim(x->∞)(f(x) / g(x)) = α, 当 α 取值不同的时候,会有什么情况发生呢? 结论: α = c (常数) => f(x) = θ(g(x)) 或者 g(x) = θ(f(x)) α = 0 => f(x) = o(g(x)) α = ∞ => g(x) = o(f(x)) 证明: α = c 时: 所有 ε > 0, 存在 N, 当 n > N 时 有 |f(x) / g(x) - .原创 2021-03-24 17:54:37 · 385 阅读 · 0 评论 -
算法分析与设计——复杂度记号
一:大O记号 含义:o(g(n)) △= {f(x)| 存在c>0, n0 >= 0,当n >= n0时, 有 f(x) <= c * g(x)} 例子:1) 2 * n ^ 2 = O(n ^ 2)2) n ^ 3 / 1000 != O(n ^ 2) 证明: 假设相等,则存在 c > 0, n0 > 0, 当 n > n0 时,有 n * n * n / 1000 = c * n * n 则有: n < 1000 * c原创 2021-03-24 16:58:01 · 1213 阅读 · 0 评论