算法导论
出现的代码并非完美版,仅供参考!!!
基础
分治模式
三个步骤
- 分解
- 解决
- 合并
渐进
- 上界
- 下界
- 紧确界
- 非渐进紧确上界
- 非渐进紧确下界
性质:传递性、自反性、对称性、转置对称性
最大子数组问题
暴力组合
C(n,2)
:效率为O(n^2)
js
var arr = [-10, -10, -9, -7, -6, 3, 20, -9, -8, -7];
// 找出全部可能的结果对比
var max_h = 0,
= 0,
max_r = arr[0];
max_s // i从0到n-1
for (var i = 0; i < arr.length - 1; i++) {
var sum = 0;
// j从i到n
for (var j = i; j < arr.length; j++) {
+= arr[j];
sum // 判断i-j这个区间是否为“最大”
if (sum > max_s) {
= i;
max_h = j;
max_r = sum;
max_s
}
}
}console.log(max_h, max_r, max_s);
分治
- 分成左右两个数组
- 左边计算最大子数组(递归)
- 右边计算最大子数组(递归)
- 中间计算最大子数组
- 比较左中右返回最大子数组
js
var arr = [-10, -10, -9, -7, -6, 3, 20, -9, -8, -7];
// 分治
function find_maximum_subarray(arr, low, high) {
if (low == high) {
return { low: low, high: high, max_sum: arr[low] };
else {
} // 递归检查并比较
var mid = Math.floor((low + high) / 2);
var left = find_maximum_subarray(arr, low, mid);
var right = find_maximum_subarray(arr, mid + 1, high);
var cross = find_max_crossing_subarray(arr, low, mid, high);
if (left.max_sum > right.max_sum && left.max_sum > cross.max_sum) {
return left;
else if (right.max_sum > left.max_sum && right.max_sum > cross.max_sum) {
} return right;
else {
} return cross;
}
}
}
// 找穿过mid的最大子数组
function find_max_crossing_subarray(arr, low, mid, high) {
var sum = 0,
// 注意不是MIN_VALUE,MIN_VALUE 属性是 JavaScript 中可表示的最小的数(接近 0 ,但不是负数)。它的近似值为 5 x 10-324。
= (right_sum = Number.NEGATIVE_INFINITY),
left_sum
max_left,
max_right;for (var i = mid; i >= low; i--) {
+= arr[i];
sum if (sum > left_sum) {
= sum;
left_sum = i;
max_left
}
}
= 0;
sum for (var j = mid + 1; j <= high; j++) {
+= arr[j];
sum if (sum > right_sum) {
= sum;
right_sum = j;
max_right
}
}
return {
: max_left,
low: max_right,
high: left_sum + right_sum,
max_sum
};
}console.log(find_maximum_subarray(arr, 0, arr.length - 1));
动态规划
0-i
的最大子数组0-i+1
的最大子数组(在已知0-i
的最大子数组的条件下可在线性时间得出)
=_=
堆排序
快速排序
数据结构
高级设计与分析技术
动态规划
与分治类似,通过组合子问题求解原问题,但动态规划应用于子问题重叠的情况(这种情况用分治会反复求解公共子问题)。
步骤:
- 刻画最优解的结构特征
- 递归定义最优解的值
- 计算最优解的值,采用自底向上的方法
- 利用计算出的信息构造最优解