zjffun blog

《算法导论》

更新于 写于

算法导论

出现的代码并非完美版,仅供参考!!!

基础

分治模式

三个步骤

  • 分解
  • 解决
  • 合并

渐进

  • 上界
  • 下界
  • 紧确界
  • 非渐进紧确上界
  • 非渐进紧确下界

性质:传递性、自反性、对称性、转置对称性

最大子数组问题

暴力组合

C(n,2):效率为O(n^2)

js
var arr = [-10, -10, -9, -7, -6, 3, 20, -9, -8, -7];
// 找出全部可能的结果对比
var max_h = 0,
  max_r = 0,
  max_s = arr[0];
// 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++) {
    sum += arr[j];
    // 判断i-j这个区间是否为“最大”
    if (sum > max_s) {
      max_h = i;
      max_r = j;
      max_s = sum;
    }
  }
}
console.log(max_h, max_r, max_s);

分治

  1. 分成左右两个数组
  2. 左边计算最大子数组(递归)
  3. 右边计算最大子数组(递归)
  4. 中间计算最大子数组
  5. 比较左中右返回最大子数组
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。
    left_sum = (right_sum = Number.NEGATIVE_INFINITY),
    max_left,
    max_right;
  for (var i = mid; i >= low; i--) {
    sum += arr[i];
    if (sum > left_sum) {
      left_sum = sum;
      max_left = i;
    }
  }

  sum = 0;
  for (var j = mid + 1; j <= high; j++) {
    sum += arr[j];
    if (sum > right_sum) {
      right_sum = sum;
      max_right = j;
    }
  }

  return {
    low: max_left,
    high: max_right,
    max_sum: left_sum + right_sum,
  };
}
console.log(find_maximum_subarray(arr, 0, arr.length - 1));

动态规划

  1. 0-i 的最大子数组
  2. 0-i+1 的最大子数组(在已知 0-i 的最大子数组的条件下可在线性时间得出)
=_=

堆排序

快速排序

数据结构

高级设计与分析技术

动态规划

与分治类似,通过组合子问题求解原问题,但动态规划应用于子问题重叠的情况(这种情况用分治会反复求解公共子问题)。

步骤:

  1. 刻画最优解的结构特征
  2. 递归定义最优解的值
  3. 计算最优解的值,采用自底向上的方法
  4. 利用计算出的信息构造最优解

钢条问题

矩阵链乘法

贪心算法

摊还分析