算法笔记

乘着上的算法导论课还有些映象,做一些记录。

  • 贪心算法
  • 分治法
  • 动态规划
    • 自顶向下
    • 自底向上
  • NP问题,规约
  • 近似算法
  • load balancing

贪心算法

it buids up a solution in small steps,choosing a desicion at each step myopically(目光短浅地) to optimize some unerlying criterion(标准)
简而言之:由局部最优—>全局最优. 有时不存在
典型问题:Interval Scheduling
* starts first(x)
* smallest interval of time (x)
* fewest conflicts (x)
* accept the request that finishes first (yes) [O(n*logn)]

Divide and conquer (分治法)

核心思想在于把输入分成若干部分,递归地求解每个部分的问题,然后把这些子问题的解组合为一个全局的解。个人以为分治法与动态规划的使用区别主要在于分解的子问题是否相关,若可以将原问题分解成多个互相不相干的子问题则可以使用分治法,否则不能使用分治法,若子问题相关可以考虑动态规划。
1. Divide:divide the problem into one or more subproblems
2. Conquer:conquer each subproblems recursively.
3. combine:solution.
eg.* 归并排序,快速排序。
* 二分查找(binary search)
* Powering a number(乘方问题)
* Fibonacci number(斐波那契数列):Bottom-up,
* Matrix:n*n matrix = 2*2 block matrix of n/2*n/2 sub matrices

动态规划(Dynamic Programming)

Basic principle for dynamic programming:Iterating over subproblems rather than computing solutions recursively。
经典问题:Subset sums(子集合求和) 和Knapsacks(背包问题),Weighted Interval Schedule。

排序与查找算法

常用的排序算法:
1. 选择排序:每次选index右侧集合最小的插入当前index位置,向右(数组尾端)移动index 适用于小数组
2. 插入排序:适合已经部分有序(倒置少的)的数列。 适用于小数组。
3. 希尔排序:高效算法,不需要理解它的性能。对于各种数组均有较好的表现。 最好手写
4. 归并排序:将两个有序数组归并成一个更大的有序数组。
先递归地将它分成两半排序, 然后将结果归并起来。时间:O(N*logN),空间:O(N)
运用了分治的思想。不适用与小数组
5. 快速排序:分治的排序算法,将一个数组切分成两个子数组, 将两部分独立地进行排序。如何进行切分是快速排序的关键。每一次切分都是将切分元素j放到了排序的最终位置,且a[lo..j-1]<= a[j] <=a[j+1…hi] ,经典问题求解中位数或第k大的数:利用切分思想而不是完全使用快排(不需要完全排序)。
6. 堆排序:典型用例,基于二叉堆求解Top K问题。非常适合数据量非常大的场合。

时间复杂度和空间复杂度比较:
排序方法平均时间最差时间额外空间稳定度备注
选择排序O(n^2)O(n^2)O(1)不稳定适合小n
插入排序O(n^2)O(n^2)O(1)稳定适合基本有序,倒置少的数据
归并排序O(nlogn)O(nlogn)O(n)稳定适合大n(因为递归)
快速排序O(nlogn)O(n^2)取决于算法,空间消耗多在递归栈中不稳定算法的效率依据是概率,适合大n(递归),在数据基本有序时效率低。
堆排序O(nlogn)O(nlogn)O(1)不稳定适合n非常大时,上述归并和快排可能空间消耗溢出,而堆排序则非常合适,常见求解问题:Top K问题

查找

三种经典的数据类型:
1. 二叉查找树:理想状态复杂度为logN,但由于插入可能不平衡,导致最坏结果可能复杂度为N(形成一个链表模式)。
2. 红黑树:平衡树,在插入和删除时保持平衡(通过旋转和改变链接的颜色), 由此实现了查找复杂度为logN. 定义为含有红黑链接并满足下列条件的二叉查找树:
1. 红链接均为左链接。
2. 没有任何一个结点同时和两个红链接相连。
3. 任意空链接到根节点的路径上的黑链接数量相同。
3. 散列表 :例如HashMap,hash函数将键转化为数组的索引,Java中的HashMap中散列函数:将处理后的key的hashcode做散列:index = hash(key) & table.length - 1,即key的hash值与数组长度-1做与运算,与取余法有同样的结果但效率更高(因为&运算比%运算效率高)而且java中取余的结果可能为负。解决冲突的方式:常用的为链表法(即拉链法),还有线性探测法。

散列表的查找比红黑树更快吗?
这取决于键的类型,它决定了hash的计算成本是否大于compareTo的比较成本。对于常见的键类型以及Java的默认实现,这两者的成本是近似的,因此散列表会比红黑树快很多,因为它所需的操作次数是固定的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值