10 算法

优质
小牛编辑
135浏览
2023-12-01

算法策略

分治法T(n)=O(nlogn)

将问题分解成规模较小、相互独立的子问题,各个击破,分而治之。

归并排序

将数列分为几个序列片段,逐趟两两归并,到底层归并成有序数列

最大子段和问题

动态规划法T(n)=O(nW)

将问题分解成互不独立子问题,保存子问题解,需要时再用,例如多项式时间算法

0/1背包问题

LCS最长公共子序列

贪心/贪婪法T(n)=O(n)

不从整体最优考虑,只根据当前信息选择某个标准,得到近似最优

背包问题

按最大价值/最小重量/最大单位重量价值先放背包的原则

活动选择问题

回溯法(通用解题法)

找出满足约束条件的所有解

在包含所有解的空间树中,按照深度优先策略,从根结点出发搜索解空间树

若结点肯定不包含解,跳过以该结点为根的子树,向其祖先结点回溯

若结点肯定包含,则进入继续按深度优先策略搜索

求问题任一解,只要搜索到问题就能结束,适合求组合数较大的问题

求问题的最优解,解空间至少包含问题的一个(最优)解

0/1背包问题

n皇后问题

分支限界法

找出满足约束条件的极大/极小解,即某种意义下的最优解

FIFO队列式(先进先出)

优先队列式

概率算法

数值概率算法

蒙特卡罗算法

拉斯维加斯算法

舍伍德算法

近似算法

放弃最优解,用近似解代替,简化/降低时间复杂度

穷举法

迭代法

递推法

递归法

算法有递归形式、非递归形式。递归式有展开法、代换法、递归树法、主方法。

排序问题

几种排序算法、索引及图的各种算法要了然于心,看见算法就知道用什么数据组织方式更高效,算法分析方法达到理解应用的水平(算法的分析过程及代码要非常清楚)

直接插入排序

冒泡排序

从数组最后开始, 两两比较元素, 顺序不对则交换元素

每一轮都冒一个泡到当前首元素位置, 减小数组长度进入下一轮

// 小到大的排序
public void test(int[] targetArr) {
  int temp = 0; //临时变量
  for (int i = 0; i < targetArr.length; i++) {
    for (int j = i; j < targetArr.length; j++) {
      if (targetArr[i] > targetArr[j]) {
        //遇到小的就交换,  保证targetArr[i]是最小的
        temp = targetArr[i];
        targetArr[i] = targetArr[j];
        targetArr[j] = temp;
      }
    }
  }
}

简单选择排序

希尔排序

快速排序

堆排序

基数排序

内部排序

外部排序

算法分析

时间复杂度

T(n)时间频度

算法花费的时间与算法中语句的执行次数成正比例

算法中的语句执行次数称为语句频度或时间频度。记为 T(n)=O(f(n))

f(n)同数量级

若有某个辅助函数f(n),使得n趋近无穷大,T(n)/f(n) 极限值不等于零,则f(n) T(n)同数量级

时间频度不同,但时间复杂度可能相同。

如:T(n)=n2+3n+4与T(n)=4n2+2n+1 它们的频度不同,但时间复杂度相同,都为O(n2)

O时间复杂度计算

算法的执行时间不随着问题规模n的增加而增长,即使有上千条语句,其执行时间是一个常数。

此时:T(n)= O(1)

有循环语句,时间复杂度由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的,例如:

x=1;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
for(k=1;k<=j;k++)
x++;

最内层语句是x++,其频度与问题规模n无直接关系,但与最外层i取值有关

最外层循环次数与问题规模n有关,此时:T(n)=O(n3/6+低次项)=O(n3)

算法的时间复杂度不仅仅依赖于问题的规模,还与输入实例的初始状态有关

i=n-1;
while(i>=0&&(A[i]!=k))
i--;
return i;

语句i--不仅与问题规模n有关,还与实例中k的取值有关

若A中没有与k相等元素,即 f(n)=n

若A的最后一个元素等于k,频度f(n)是常数0

空间复杂度

空间复杂度是指运行完一个程序所需内存的大小

一个算法所需的存储空间用f(n)表示。S(n)=O(f(n))

其中n为问题的规模,S(n)表示空间复杂度

经典算法

组合问题

斐波那契数列

马踏棋盘问题

货朗担问题

迷宫问题

汉诺塔问题

约琴夫环问题