抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

阿湫o

一只前端崽

贪心算法和动态规划

贪心算法

当遇到一个求解全局最优解问题时,如果可以将全局问题切分为小的局部问题,并寻求局部最优解,同时可以证明局部最优解累计的结果就是全局最优解,则可以使用贪心算法

找零问题:

示例:假设你有一间小店,需要找给客户 46 分钱的硬币,你的货柜里只有面额为 25 分、10 分、5 分、1 分的硬币,如何找零才能保证数额正确并且硬币数最小

JavaScript 代码:

/**
 * 得到一个找零的结果: [25, 10, 10, 1]
 * @param {*} total 要找零的总额
 * @param {*} denos 拥有的面额
 */
function exchange(total, denos) {
    if (total <= 0) {
        return [] //不用找零
    }
    // 寻找最大的面额,同时要保证面额小于等于total
    var max = 0
    for (var i = 0; i < denos.length; i++) {
        var deno = denos[i]
        if (deno > max && deno <= total) {
            max = deno
        }
    }
    // max记录这一次的解(局部最优解)
    var result = [max]
    var next = exchange(total - max, denos) //得到后续的局部最优解
    result = result.concat(next) //拼接之后,就是整体最优解
    return result
}

// 要找的总金额
var total = 51
// 拥有的面值
var denos = [30, 25, 10, 5, 1]
var result = exchange(total, denos)
console.log(result) // [25, 10, 10, 1]

动态规划

分治法有一个问题,就是容易重复计算已经计算过的值,使用动态规划,可以将每一次分治时算出的值记录下来,防止重复计算,从而提高效率。

青蛙跳台阶问题:

有 N 级台阶,一只青蛙每次可以跳 1 级或两级,一共有多少种跳法可以跳完台阶?

Js 代码:

var num1 = 0
// 不使用动态规划
function count1(total) {
    num1++
    if (total === 0) return 0
    if (total === 1) return 1
    if (total === 2) return 2
    return count1(total - 1) + count1(total - 2)
}

var num2 = 0
//使用动态规划优化效率
function count2(total) {
    var cache = {} //缓存已经计算过的结果
    function _count(total) {
        if (cache[total] !== undefined) {
            return cache[total] //直接使用缓存结果
        }
        num2++
        var result
        if (total === 0) result = 0
        else if (total === 1) result = 1
        else if (total === 2) result = 2
        else {
            result = _count(total - 1) + _count(total - 2)
        }
        cache[total] = result
        return result
    }
    return _count(total)
}

console.time('没有动态规划')
var result1 = count1(25)
console.log(result1, '计算了' + num1 + '次')
console.timeEnd('没有动态规划')
console.time('动态规划')
var result2 = count2(25)
console.log(result2, '计算了' + num2 + '次')
console.timeEnd('动态规划')

// 121393 "计算了150049次"
// 没有动态规划: 5.377197265625ms
// 121393 "计算了25次"
// 动态规划: 0.339111328125ms

由上述代码运行的结果可知,动态规划可以大大的提高程序的效率




网站内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站总访问量为 访客数为

本站使用 Volantis 作为主题 载入天数...载入时分秒...