Algorithm:算法基础

一 算法

定义:有限步骤内求解某一问题所使用的一组定义明确的规则。

[针对问题的解决方案][ 为解决问题,而采取的方法与步骤]

内容:设计算法、表示算法、确认算法、分析算法、验证算法

特性:有穷性[有限时间执行完毕]、确定性[执行唯一]、可行性、输入、输出

表示方法:自然语言、程序流程图、程序【顺序、选择、循环】

分类:

同一问题——有多种解决问题的算法

特定问题、特定约束条件——合适的算法

 

二算法分析

算法复杂度

算法复杂度:算法运行所需的资源。

1时间复杂度

程序执行次序(频度):f(n)的数量级

公式:T(n) = 0(f(n))  其中T(n) 就是算法的时间复杂度,n表示是输入到算法的数据模块

常见:01)常量级 0n)线性级 0n^2)平方级

2空间复杂度

重点:不超过内存,空间换时间

 

基础算法

递归

定义:一个过程[函数],直接\间接调用自己本身的过程[函数]

设计:1确定递归公式   2确定边界条件\终止条件

问题:求数组中最大的数、1+2+。。。+n、求n个整数的平均值、求n个自然数的最大公约数和最小公倍数、生兔子问题、斐波那契数列、汉诺塔同类问题

回溯

定义:

设计:1用栈保存前进状态    2制定约束条件

问题:全排列、n个皇后

排序

 

 

 

三 算法设计

1原则

原则:正确性、可读性、健壮性、高效率与低存储量

1正确性

<1没有语法错误

<2 根据正确的输入的值得到满足要求的输出结果

<3 根据错误的输出的值满足规格说明的输出结果  [正确的标准——]

<4 对于精心设计、极其刁难的测试数据满足要求的输出结果

<5

2可读性:设计算法的目的是计算机执行\便于阅读——[评判算法]

3健壮性:输入数据非法时,算法应恰当地做出反应\处理,不中断程序的情况下,返回一个表示错误或者错误性质的值,以便于在更高抽象层次上进行处理

4高效率: 算法的效率-算法的执行时间—【时间复杂度】

低存储量:算法的存储量-算法执行过程中所需的最大存储空间—【空间复杂度】

 

2设计步骤

1建立数学模型         分析问题—抽象出数学模型

2确定数据结构与算法   确定数据结构—设计对数据结构实施操作的算法

3选用语言             算法—转化—程序

4调试并运行

 

3设计思想

穷举、递推、递归、分治、概率

1穷举算法思想

定义:从所有可能结果

步骤:[计算每种可能的结果]——[判断结果是否符合要求]——[符合,输出][不符合,返回第一步]

问题:鸡兔同笼

2递推算法思想

定义:根据已知条件,利用特性关系推导中间推论,直到得到结果

问题:斐波那契数列 等

3递归算法思想

定义:大问题转换成同类问题的子问题,然后递归调用函数表示问题的解[终止条件]

问题:求阶乘、

4分治算法思想

定义:大问题分解成相互独立的子问题[与原问题性质相同],然后逐步求出子问题的解

问题:查找假币

5概率算法思想

数值概率算法、蒙特卡罗算法、拉斯维加斯算法、舍伍德算法

 

设计思路

分治法、动态规划、贪心算法、

1分治法

一思想

<1定义:将1个规模为n的问题分解为k个规模较小的子问题。[子问题相互独立、且与原问题相同],递归解决子问题,然后将子问题的解合并得到原问题的解。

<2规划子问题:

-集合论:原集合问题的划分,子问题不相交且规模类型相同

-最优子结构:子问题类型相同

-子规模相近

<3方法

divide—and—conquer(P)

{if(|P|<=n0) adhoc(P);

divide P into samller subinstances P1,P2,…Pk;

for(int i=1;i<k;i++){yi=divide—and—conquer(Pi);}

return merge(y1,y2,…,yn)}

二问题

Fibonacci数列、排列问题、整数规划问题、Hanoi塔问题、二分搜索、合并排序、快速排序、大整数乘法、Strassen矩阵乘法(n行m列选最大的和)、

三复杂度

主定理:T(n)=aT(n/b)+f(n),a>=1,b>1【f(n):给定的多项式函数,刻画分值算法,生成a个子问题,每个问题的规模是原来的1/b,分解合并步骤共消耗f(n)】

T(n)的复杂度:

1若f(n)<n^(log(a/b)),则T(n)=n^(log(a/b))

2若f(n)=n^(log(a/b)),则T(n)=n^(log(a/b))logn

3若f(n)>n^(log(a/b)),则T(n)=f(n)

2动态规划

一思想

<1定义:用一个表记录所有可以解决问题子问题的答案,不管以后是否会用到,只要计算,就将结果存入表中。

基本要素:

1最优子结构:问题的最优解包含了子问题的最优解

2重叠子问题:递归算法有很多子问题重叠,则用一个表将已经求解过的子问题结果保存。

二基本步骤

【1找出最优解性质,刻画结构特征】—【2递归定义最优值】—【3自底向上计算最优值】—

【4根据计算最优值得到的信息,构造最优解】

三问题

矩阵连乘、最长公共子序列、0-1背包问题

四 应用—备忘录方法

动态规划      备忘录方法

<1相同  用一张表保存子问题的答案,下次求解时查看表的答案,不用重新计算。 

<2不同递归方式:自底向上   |  自顶向下

<3使用条件:所有子问题都至少解一次| 部分子问题不必求解

3贪心算法

一思想

<1定义:不从整体最优考虑,做出的选择只是某种意义上的局部最优选择

<2要素:

-贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择[贪心选择],来达到

-最优子结构;问题的最优解包含其子问题的最优解

二问题

活动安排问题(最早截止时间优先)、背包问题(权重空间比值最大者优先)、哈夫曼编码(频率大者优先)、单源最短路径(局部最短路径优先)、最小生成树(prim[与源集合相连权值最小边优先]\ kruskal[集合中边权值最小优先])、多级调度问题(长作业优先)

三区别     贪心算法|   动态规划

条件

方法:

总结:分治divide—and—conquer[Divid—conquer—Combine]

 

 

五 功能问题

图形

规律

功能

统计:

分页:分页:(y+x-1)/x    逆向运算[结果—推导—>方式]  p=(y+x-1)/x

 

问题

最佳浏览路线问题

删数问题

 

算法分析与设计

P问题、非P问题、NP问题、NPC问题

P问题

非P问题

NP问题

NPC问题

 

 

数字在排序数组中出现次数。

题目:统计一个数字在排序数组中出现的次数。

思路:

  1. 预估时间复杂度,最复杂的情况是,顺序扫描,统计K出现的次数,时间复杂度是o(n)
  2. 使用类似2分查找,时间复杂度应该是o(logn)

class Solution{

 public: int getNumberOfK(vector<int> &data, int begin, int end, int k) {

int i = begin,j = end,mid = (i + j)>>1;

if(i>j)return 0;

if(i==j) return data[mid]==k;

 if(data[mid]==k) return 1 + getNumberOfK(data,begin,mid-1,k)

+getNumberOfK(data,mid+1,end,k);

if(data[mid] < k) return getNumberOfK(data,mid + 1,end,k);

return getNumberOfK(data ,begin, mid - 1,k); } };

 

 

http://www.docin.com/p-1945081530.html

递归

递推

回溯:前进状态、约束条件

排序:

选择排序:

插入排序

冒泡排序:

快速排序:

希尔排序

堆排序

二叉树排序

归并排序

线形排序:

<1计数排序

<2桶排序

<3基数排序

查找

顺序查找

二分查找

二叉树排序查找

哈希表查找:哈希表

穷举策略   从可能解的集合中枚举全部元素,条件校验?解:误解

贪心策略   从问题的初始状态出发、通过若干次贪心选择,得出最优解

特点:贪心选择性质、局部最优解

分治策略(Divide and conquer) 规模为n的问题,分为k规模较小的子问题。递归解决子问题,合并解

[应用:快速排序]

搜索:

深度优化搜索

过度优化搜索

戴克斯特拉算法

动态规划

朴素贝叶斯分类

 

 

 

选择排序:

思路:

步骤:排序的序列处理n-1遍。

第一遍:L[1…n]最小者,与L[1]交换位置

第二遍:L[2…n]最小者,与L[2]交换位置

第i遍:L[i…n]最小者,与L[i]交换位置

插入排序

思路

步骤:经过i-1遍处理后,L[1,…,i-1]已经排好序.

第i遍处理:将L[i]插入L[1,…,i-1]的适当位置p,原来p后的元素右移

问题:

冒泡排序=交换排序

思路:对排序的记录的关键字进行两两比较,如果反序,则交换,直到无反序记录。

步骤:

快速排序

思路:依据分治法策略,一个串行(list)分成一个子串行(sub-list)

步骤

1基准(pivot) :数列中挑出一个元素

2分区(partition): 重新排序,所有元素比基准值小的摆放在基准前面,大的在后面。分区退出后,该基准处于数列的中间位置。

3递归(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

希尔排序

思路:将整个无序序列分割成若干小的子序列分别进行插入排序、冒泡排序

序列分割:

堆排序与二叉树排序

堆排序

二叉树排序

归并排序Merge sort

思路:依据分治法策略

步骤:

归并:多个有序数列合成一个有序数列

二路归并:两个有序数列合成一个有序数列

归并排序:n长度为1的子序列,两两排序最后变为有序序列。

线形排序

计数排序

桶排序

基数排序

排序比较:

稳定性:插入\冒泡\二叉树\二路并归\线形-稳定,选择\希尔\快速\堆-不稳定

顺序查找:顺序逐个比较,   查找值==结点值?成功:失败

二分法查找

思路:从数组中间元素查找,如果查找元素是中间元素, 搜索过程结束\如果查找元素大于\小于中间元素,则在数组大于\小于中间元素那一侧查找—跟开始一样从中间元素开始比较\如果某一步骤数组为空,代表找不到

二叉树排序查找

哈希表

哈希表\散列表

哈希函数:H(k)=k\H(k)=a*k+b(线性函数)  存储位置K、关键字k

查找:递归方式

 

线性查找算法BFPRT

思路:从n个元素的序列中选出第k大\小的元素

步骤:五位算法

1将n个元素每5个一组,分成n/5组(上界)

2取出每组的中位数,任意排序。[插入排序]

3递归调用selection算法查找上一步所有的中位数,设为x,偶数个中位数时,设定为中间小的

4用x分割数组,设小于等于x的个数为k,大于x的个数为n-k

5若i==k,返回x;\若i<k,在小于x的元素递归查找第i小的元素\若i>k,在大于x的元素队规查找第i-k小的元素

深度优化算法DFS(Depth-First-Search)【盲目搜索】

思路:

步骤:

过度优化搜索BFS(Breadth-First-Search) 【图形搜索】

思路:

步骤:

戴克斯特拉Dijkstra

思路:

步骤:

动态规划Dynamic programming[数学、计算机、经济学]

定义:复杂问题分解为简单子问题,分别求解,合并解。(耗时少于朴素算法)

适用:有重叠子问题、最优子结构性质问题

步骤:1解决每个子问题一次,从而减少计算量;2一旦某个给定子问题解得出,则记忆化存储;3下次同一个子问题求解时,直接查表

背包问题

朴素贝叶斯分类算法

贝叶斯分类:概率推论[各种条件存在不确定,仅知概率,完成推理和决策]

贝叶斯分类器:自然概率模型,独立假设[样本与其他特征不相关]

参数估计:最大似然估计法

思路:基于贝叶斯定理的简单概率分类算法。

步骤:

猜你喜欢

转载自blog.csdn.net/ddhmbbklyk2018/article/details/81568667