该系列为清华邓俊辉老师数据结构mooc课程总结,向邓老师致敬!
eg:计算工具:尺规工具
计算=信息处理 计算模型=计算机=信息处理工具
冒泡排序:借助sorted标志 ,可提前退出
void bubblesort1A(int A[], int n) {
bool sorted = false; //首先假定尚未排序
while (!sorted) {
sorted = true; ?//假定已经排序
for (int i = 1; i < n; i++) {
if (A[i - 1] > A[i]) {
swap(A[i - 1], A[i]);
sorted = false; //因整体排序不能保证,清楚排序标志
}
}
n--; //可以缩短待排序序列的有效长度
}
}
算法分析主要关注:正确+成本
时间复杂度T(n);特定算法处理规模为n的问题所需的时间,关注最坏情况
渐进复杂度(渐进上界):大O记号
空间复杂度:算法所需存储空间的多少,不计入原始输入所占用的空间
迭代乃人工,递归方神通
int sum(int A[], int n) {
if (n < 1) return 0; //递归基
else
return sum(A, n - 1) + A[n - 1]; //递归:前n-1项和,再累计第n-1项
}
void max2(int A[], int lo, int hi, int & x1, int & x2)
{
// 递归基, 总共只有 2个/3个 元素
if (lo + 2 == hi) {* ... * ; return;}
if (lo + 3 == hi) {* ... * ; return;}
// 递归过程,分为两组,两边至少2个元素
int mi = (lo + hi)/2;
// 递归
int x1L, x2L;
max2(A, lo, mi, x1L, x2L);
int x1R, x2R;
max2(A, mi, hi, x1R, x2R);
// 每个递归实例所需操作
if (A[x1L] > A[x1R])
{
x1 = x1L;
x2 = (A[x2L] > A[x1R]) ? x2L : x1R;
}
else
{
x1 = x1R;
x2 = (A[x1L] > A[x2R]) ? x1L : x2R;
}
}
为使分治策略有效,必须要保证子问题之间相互独立,即各子问题可独立求解,而无需借助其他子问题的原始数据或者中间结果
int fib (int n) {
int f = 1, g = 0; // fib(-1), fib(0)
while (n-->0) {
g = f + g;
f = g - f;
}
return g;
}
实例:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有多少总跳法,并分析算法的时间复杂度。
变化:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级…它也可以跳上n级。此时该青蛙跳上一个n级的台阶总共有多少种跳法?
分析:
int jumpFloorII (int number) {
if (number == 0)
return 0;
int f = 1; // fib(1)
for (int i=1; i
递推公式:用 C[i,j]来表示表格中 [Ai,Bj] 处的长度。
参考:https://blog.csdn.net/hrn1216/article/details/51534607
int lcs (string a, string b){
int l1 = a.size();
int l2 = b.size();
int DP[l1+1][l2+1];
memset(DP, 0, sizeof(DP));
for(int i = 1; i <= l1; i++)
for(int j = 1; j <= l2; j++)
if(a[i - 1] == b[j - 1])
DP[i][j] = DP[i - 1][j - 1] + 1;
else
DP[i][j] = max(DP[i][j - 1], DP[i - 1][j]);
return DP[l1][l2];
}
leetcode 300. Longest increasing sequence
Given an unsorted array of integers, find the length of longest increasing subsequence.
Example:Input: [10,9,2,5,3,7,101,18] Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4
参考: https://panxiaoxie.cn/
动态规划常常适用于有重叠子问题[1]和最优子结构性质的问题。
“对于 longest increasing subsequence 里面就存在最优子问题。对于一个序列,每增加一个元素,都可以看作一个子问题。 子问题的解是固定的,但是子问题与当前步的结合又是动态变化的。比如这里,当前 i 位置的值大于 j 的值和小于 j 的值的处理方式就不太一样。我们要做的就是找出这个规律 (递推公式),然后根据填写好的子问题的解的表格,进一步扩大问题规模。”
Optimal Substructure: 设 arr[0…n-1] 为输入数组,L[i]是在第i个位置结束的增加子序列
则L(i) 可以递归的表达: L(i) = 1 + max( L(j) ) where 0 < j < i and arr[j] < arr[i]; or L(i) = 1, if no such j exists. 最终返回 max(L(i)) where 0 < i < n.
class Solution {
public:
int lengthOfLIS(vector& nums) {
if (nums.size() == 0) return 0;
int dp[nums.size()];
dp[0] = 1;
for (int i=1; i< nums.size(); i++){
dp[i] = 1;
for (int j=0; j < i; j++){
if (nums[i] > nums[j] && dp[i] < dp[j]+1){
dp[i] = dp[j] + 1;
}
}
}
return *max_element(dp, dp+nums.size());
}
};