课上所学,课下实现,顺便学下Java
1 归并排序
1.1 自顶向下的归并排序
如果它能够将两个子数组排序,他就能通过归并两个子数组来将整个数组排序。
1 | public class Merge { |
1.11 对小规模子数组使用插入排序
因为递归会使小规模问题中的递归调用过于频繁,所以改进对他们的处理就能改进整个算法。插入排序很可能在小数组上比归并排序更快。
1.12 测试数组是否已经有序
添加一个判断条件,如果a[mid]小于等于a[mid+1],我们就认为数组是已经有序的,并跳过merge()方法。
1.13 将不重复元素复制到数组
1.2 自底向上的归并排序
这个merge的地方很巧妙,感觉这种写法更清晰一点,下面那种用while的我自己都快把自己绕晕了
1 | public class MergeBU { |
自己用C写的
1 | void Merge(int *A,int start,int mid, int end) |
2 堆实现的优先队列
1 | package com.company; |
3 快速幂
思路类似于多项式求和
1 | int pow2(int i, int j) |
4 求多数元素
在原序列中去除两个不同的元素以后,原序列中的多数元素在新的序列中还是多数元素O(n)的时间复杂度
1 | int majorityElement(int *a,int len) |
5分治
5.1 求最大最小值
1 | /*寻找最小值需要进行n-1次比较,这已经是最优结果。如果需要同时找出最大值和最小值,可以直接进行两次查询, |
5.2 求第k小元素
1 | //划分——每次划分唯一确定一个元素位置 |
6 动态规划
6.1 求最长子序列
1 |
|
6.2 背包问题
问题描述:
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
基本思路 :
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。 用子问题定义状态:即f[i][v]
表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
代码如下
1 | for(int i = 1; i <= n; i++) |
优化空间复杂度:
以上方法的时间和空间复杂度均为O(VN),其中时间复杂度应该已经不能再优化了,但空间复杂度却可以优化到O(V)
只用一维数组的话要注意到,每次他都会利用上一行左边的值,那么我们只要每行从右向左遍历,那么就不会覆盖到原来的值了。
1 | for(int i = 1; i <= n; i++) |