14. 动态规划&贪心算法

574 阅读1分钟

高级算法

动态规划

动态规划被认为是与递归相反的技术, 递归从顶部分解问题,然后解决小的问题

本质上,递归的执行效率很低,很多语言都没有将递归作为高级编程的语言特性。

斐波那契数列

// 0, 1, 1 ,2 ,3 ,5, 8, 13....

function Fib(n) {
        var i = 0
        if (n < 2) {
            return n
        } else {
            return Fib(n-1) + Fib(n-2)
        }
    }
 function iterFib(n) {
        var last = 1
        var nextLast = 1
        var result = 1
        for (var i = 2; i < n; n++) {
            result = last + nextLast
            nextLast = last
            last = result
        }
        return result
    }

寻找最长公共子串

reaven havoc 公共的最长子串是av

暴力拆解: 现在给出两个字符串A,B 我们将A的第一个字符开始于B对应找到他们的最长子串, 如果没有找到就匹配第二个字符

动态规划: 使用一个二维数组存储两个字符串相同位置的字符比较结果。 初始化时,该数组每一个元素都被设置为0,每次两个数组发现了匹配就将数组对应的行和列的元素加1。

记录下找到了多少个匹配项,当算法执行完毕时,这个变量会结合一个索引来取出最长的公共子串

function lcs(word1, word2) {
        var max = 0
        var index = 0
        var lcsarr = new Array(word1.length + 1)
        for (var i = 0; i <= word1.length + 1; i++) {
            lcsarr[i] = new Array(word2.length + 1)
            for (var j = 0; j <= word2.length + 1; ++j) {
                lcsarr[i][j] = 0
            }
        }
        for (var i = 0; i <= word1.length + 1; i++) {
            for (var j = 0; j <= word2.length + 1; ++j) {
                if (i == 0 || j == 0) {
                    lcsarr[i][j] = 0
                } else {
                    if (word1[i - 1] == word2[i - 1]) {
                        lcsarr[i][j] = lcsarr[i - 1][j - 1] + 1
                    } else {
                        lcsarr[i][j] = 0
                    }
                }
                if (max < lcsarr[i][j]) {
                    max = lcsarr[i][j]
                    index = i
                }
            }
        }
        var str = ''
        if (max == 0) {
            return ''
        } else {
            for (var i = index - max; i <= max; i++) {
                str += word2[i]
            }
            return str
        }
    }

背包问题

保险箱里 5件物品 尺寸是3,4,7,8,9 他们的价值分别是 4,5,10,11,13,而背包空间为16. 那么恰当的方式就是拿走第三和第五个。

    // 背包问题
    function max(a, b) {
        return (a > b) ? a : b
    }

    function knapsack(capacity, size, value, n) {
        if (n == 0 || capacity == 0) {
            return 0
        }
        if (size[n - 1] > capacity) {
            return knapsack(capacity, size, value, n - 1)
        } else {
            return max(value[n - 1] +
                knapsack(capacity - size[n - 1], size, value, n - 1),
                knapsack(capacity, size, value, n - 1))
        }
    }

动态规划

function DKnapsack(capacity, size, value, n) {
        var K = []
        for (var i = 0; i <= capacity; i++) {
            K[i] = []
        }
        for (var i = 0; i <= n; i++) {
            for (var w = 0; w <= capacity; w++) {
                if (i == 0 || w == 0) {
                    K[i][w] = 0
                } else if (size[i-1] <= w) {
                    K[i][w] = max(value[i-1] + K[i-1][w-size[i-1]], K[i-1][w])
                } else {
                    K[i][w] = K[i-1][w]
                }
                console.log(K[i][w] + ' ')
            }
        }
        return K[n][capacity]
    }

贪心算法

你去买东西,找零63美分,店员根据贪心算法他会 2 * 25 + 1 * 10 + 3 * 1 这样是的在没有50美分的硬币情况下给出的硬币数量最少、