• 基础知识概要


    1.算法复杂度——O记号,Ω符号,θ符号

    T(n)=O(f(n)) iff  c>0,当 n足够大时,有T(n)<c*f(n)
    T(n)=Ω(f(n)) iff  c>0,当 n足够大时,有T(n)>c*f(n)
    T(n)=θ(f(n)) iff  c1c2>0,当 n足够大时,有c1*f(n)>T(n)>c2*f(n)

    2.复杂度类型

    1)常数复杂度——O(1):效率最高

    2)对数复杂度——O(logn):lnN,lgN,log,这类算法非常有效,复杂度无限接近于常数,logN=O(N^c)

    3)多项式复杂度——O(n^c):

    4)线性复杂度——O(n):所有O(n)类函数

    5)指数复杂度——O(a^n):这类算法计算成本增长极快,通常被认为不可忍受

    3.复杂度分析的主要方法:

    迭代:级数求和

    递归:递归跟踪+递推方程

    猜测+验证

    4.封底估算

    1天=24hr*60min*60sec=25*4000=10^5sec

    一生=一世纪=100yr*365=3*10^4day=3*10^9sec

    三生三世=10^10sec

    5.迭代和递归

    计算任意n个整数之和

    迭代:
    int sum=0;//O(1)
    for
    (int i=0;i<n;i++)//O(n) sum+=A[i];O(1) return sum;O(1)
    递归:
    return (n<1)?0:sum(A,n-1) +A[n-1];
    在分析复杂度的时候都会把递归调用语句抹除
    递归跟踪分析:检查每个递归实例sum(A,n-1),累计所需时间,其总和即算法执行时间,面对更加复杂的函数时,应用范围有限:T(n)=O(1)*(n+1)
    递推方程分析:为求解sum(A,n),需递归求解规模为n-1的问题sum(A,n-1)//T(n-1)
    再累加上A[n-1]//O(1)
    递归基:sum(A,0)//O(1)
    递推方程:T(n)=T(n-1)+O(1)
    T(0)=O(1)
    推导:T(n)-n=T(n-1)-(n-1)

    6.减而治之(decrease and conquer)
    求解一个大规模的问题,可以将其划分为两个子问题:其一平凡,另一规模缩减

    分别求解子问题,由子问题的解得到原问题的解

    当程序到达递归基,则返回

    递归基:判断递归是否继续的条件

    7.分而治之

    为求解一个大规模的问题,可以将其划分为若干个规模大体相当的子问题分别求解,由子问题的解得到原问题的解

    数组求和:二分递归
    sum(int A[], int lo, int hi){
        if(lo==hi) return A[lo];
        int mid=(lo+hi)/2;
        return sum(A, lo, mid)+sum(A, mid+1, hi);        
    }
    递归跟踪分析:T(n)=各层递归实例所需时间之和(将递归调用的语句去掉)
             =O(1)*(2^0+2^1+2^2+...+2^logn)=O(n)
    从递推的角度看:
    为求解sum(A,lo,hi),需递归求解sum(A,lo,mid)和sum(A,mid+1,hi) //2*T(n/2)
    进而将子问题的解累加 //O(1)
    递归基:sum(A,lo,lo) //O(1)
    递推关系:T(n)=2T(n/2)+O(1)
    T(1)=O(1)

     8.动态规划(由自顶向下的递归,改为由自底向上的迭代)

    make it work,make is right(递归)

    make it fast(迭代)

    通过递归找出了算法的本质,并且给出一个初步的解之后,再将其等效的转化为迭代的形式

    斐波那契数:fib(n)=fib(n-1)+fib(n-2)

    复杂度:T(0)=T(1)=1,T(n)=T(n-1)+T(n-2)+1

    T(n)=O(n^2)

    public int fibonacci(int n) {
            // write your code here
            int f=0;
            int g=1;
            
            while(--n>0){
                g=g+f;
                f=g-f;
            }
            return f;
        }

    最长公共子序列(LCS):

    对于序列A[0, n]和B[0, m],LCS(A, B)无非三种情况:

    1)若n=-1或m=-1,则取作空序列(“”)  //递归基

    2)若A[n]='X'=B[m],则取作LCS(A[0,n),B[0,m))+'X'  //减而治之

    3)若A[n]!=B[m],则在LCS(A[0,n],B[0,m))与LCS(A[0,n),B[0,m])中取更长者  //分而治之

     9.算法的有穷性

    程序不一定是算法

    10.

    S包含n个正整数,求和为2m,S是否有子集满足该子集的和为m?

    np-complete问题

    11.

  • 相关阅读:
    Matlab随笔之三维图形绘制
    Matlab随笔之模拟退火算法
    Matlab随笔之矩阵入门知识
    Matlab随笔之求解线性方程
    Matlab随笔之分段线性函数化为线性规划
    Matlab随笔之指派问题的整数规划
    Matlab随笔之线性规划
    Android单位转换 (px、dp、sp之间的转换工具类)
    Android禁止输入表情符号
    设计模式之策略模式
  • 原文地址:https://www.cnblogs.com/lvjygogo/p/8516928.html
Copyright © 2020-2023  润新知