includeios / document

js玄学
27 stars 2 forks source link

动态规划 #9

Open includeios opened 5 years ago

includeios commented 5 years ago

动态规划

题目 1+1+1+1+1+1

A:上面的等式值是多少呀
B:(奋笔疾书计算)...等于6

A:那在上面的等式前面再写上"1+"呢?1+1+1+1+1+1+1,现在等于多少呀
B:(迅速作答)等于7
A:这次你为什么这么快就算出来了呀?
B:因为这次只要在6的基础上再加1就可以了,不需要再重新计算一遍了

动态规划的核心就是:记住已经解决过的子问题的解。those who cannot remember the past are condemned to repeat it

题目一:斐波拉契数列

fibonacci(0) = 0

fibonacci(1) = 1

fibonacci(n) = fibonacc(n-1) + fibonacc(n-2)

//递归
const fib = (n)=>{
    if(n <= 1) return n
    return fib(n-1)+fib(n-2)
}

image

//自顶向下的备忘录法
const Memo = []
const fib = (n,Memo)=>{
    //如果备忘录里已经有了记录,直接返回
    if(Memo[n]) return Memo[n]

    if(n <= 1)  Memo[n] = n
    else Memo[n] = fib(n-1,Memo) + fib(n-2,Memo)

    return Memo[n]
}

fib(6,Memo)
//自低向上法
const fib(n){
    if(n <= 1) return n
    let Memo_i = 1 //n
    let Memo_i_1 = 1 //1
    let Memo_i_2= 0 //0

    for(let i = 2;i<=n;i++){
        Memo_i = Memo_i_1 + Memo_i_2
        Memo_i_2 = Memo_i_1
        Memo_i_1 = Memo_i
    }

    return Memo_i
}
最长回文子串

image

dp[i][j] = 1  //s.substr(i,j)是回文串

const longestPalindrome = (s)=>{
    const len = s.length
    if(len <= 1) return s
    let start = 0//回文串起始位置
    let max = 1  //回文串最大长度

    const dp = [][]

    //首先计算长度为1和长度为2的子回文串
    for(let i = 0;i<len;i++){
        dp[i][i] = 1
        if(i<len - 1 && s[i] == s[i+1]){
            dp[i][i+1] = 1
            max = 2
            start=i
        }
    }

    //从计算长度为3的子回文串开始,一直到计算长度为length的子回文串
    for(let l = 3;l<=len;l++){
        for(let i = 0;i+l<=len;i++){
            const j = i+l-1 //终止字符位置
            if(s[i] == s[j] && dp[i+1][j-1] == 1){
                dp[i][j] = 1
                start = i
                max = l
            }
        }
    }

    return s.substr(start,max)
}