【数据结构与算法】三个经典案例带你了解动态规划

这篇具有很好参考价值的文章主要介绍了【数据结构与算法】三个经典案例带你了解动态规划。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

从表中我们可以看到,最大的公共子串长度为2,一共有两个长度为2的公共子串,分别是第一个字符串的第2个字符到第3个字符和第一个字符串的第3个字符到第4个字符,即 baac

根据上面的方法,我们来用代码封装一下求取最大公共子串的函数

function publicStr(s1, s2) {

// 创建一个表

let table = []

// 记录最大的公共子串长度

let max = 0

// 子串进行比较,将表填完整

for(let i = 0; i <= s1.length; i++) {

table[i] = []

for(let j = 0; j <= s2.length; j++) {

// 若行表头或列表头为0,格子里填0

if(i == 0 || j == 0) table[i][j] = 0;

// 若字符比对不相同

else if(s1[i - 1] !== s2[j - 1]) table[i][j] = 0;

// 字符比对相同

else {

// 当前格子的值等于左上角格子的值+1

table[i][j] = table[i - 1][j - 1] + 1

// 判断max是否为最大公共子串的长度

if(table[i][j] > max) max = table[i][j]

}

}

}

// 记录所有的最大公共子串的信息

let items = []

// 遍历整个表,找到所有子串长度为max的子串的最后一个字符的索引

for(let i = 0; i < s1.length; i ++) {

let current = table[i]

for(let j = 0; j < s2.length; j ++) {

if(current[j] === max) items.push(i)

}

}

console.log(最大子串长度为${max});

console.log(长度为${max}的子串有:);

for(let i in items) {

let start = items[i] - max

console.log(${s1.slice(start, start + max)});

}

}

我们用上述例子来验证一下该函数是否正确,同时我还打印了一下表的结果,大家可以跟实例中的比对一下是否正确

let s1 = ‘abaccd’

let s2 = ‘badacef’

publicStr(s1, s2)

/* 打印结果:

最大公共子串长度为2

长度为2的子串有:

ba

ac

表:[

[0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 1, 0, 1, 0, 0, 0],

[0, 1, 0, 0, 0, 0, 0, 0],

[0, 0, 2, 0, 1, 0, 0, 0],

[0, 0, 0, 0, 0, 2, 0, 0],

[0, 0, 0, 0, 0, 1, 0, 0],

[0, 0, 0, 1, 0, 0, 0, 0]

]

*/

四、案例三:背包问题

===================================================================

背包问题也算是一个非常经典的问题,假设现在你的面前有4种珠宝,它们的重量分别为 3345 ,它们的价值分别为 4679,现在你有一个能装下重量为 8 的物品,请问你会如何挑选才能使利益最大化?

当然最简单的办法就是写出所有的组合,然后计算每种组合的价值,然后就能获得利益最大化的方案

这用递归实现是非常简单的,代码如下

// 封装一个判断大小的函数

function max(v1, v2) {

return v1 > v2 ? v1 : v2

}

// 主函数,用于判断当前背包容量下,存放某个物品的最大收益

// 参数:背包容量、存放每个物品重量的数组、存放每个物品价值的数组、物品标号

function knapsack(capacity, size, value, n) {

// 如果没有物品了或者背包没容量了,则最大收益为0

if(n == 0 || capacity == 0) return 0;

// 物品n的重量大于背包容量

else if(size[n - 1] > capacity) {

// 返回上一个物品的最大收益

return knapsack(capacity, size, value, n - 1)

}

// 物品n的重量小于背包容量

else {

// 此时有两种选择:第一种:拿该物品 ; 第二种:不拿该物品

// 我们要取其中收益最大的方案,因此用到max函数

return max(value[n - 1] + knapsack(capacity - size[n - 1], size, value, n - 1), knapsack(capacity, size, value, n - 1))

}

}

// 代码测试

let capacity = 8

let size = [3, 3, 4, 5]

let value = [4, 6, 7, 9]

let n = 4

let res = knapsack(capacity, size, value, n)

console.log(res) // 15 , 表示最大收益价值为15

正如我们文章开头所说的,这样的递归效率总归是不太高的,因此我们要将其用动态规划实现,并且我们将需求改变一下,不光要求出最大收益价值,还要知道是拿了哪几样物品。

同样的,我们先创建一个表,用来记录每一种物品在任一背包容量下的最大收益

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

很明显,当背包容量为0时,我们能获得的最大收益一定为0;表中物品编号为0的这一行全部都要填上0,因为这是我们添加的对照行,并没有编号为0的物品,因此结果如图所示:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

现在我们从编号为1的物品开始,判断其在背包容量为 1 ~ 8 的情况下,我们能获取到的最大利益为多少。显而易见,物品1的重量为3,因此当背包容量小于3时,最大收益都为0;当背包容量大于等于3时,因为还没有考虑别的物品,因此我们能获取的最大收益就等于物品1的价值,即等于4,结果如图所示:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

接着我们考虑编号为2的物品在背包容量为 1 ~ 8 的情况下,我们能获取到的最大利益为多少。

首先知道物品2的重量为3,因此在背包容量小于3时,我们无法放入物品2,那么此时的最大收益就等于在当前背包容量下,放入物品1的最大收益;

当背包容量大于等于3时,我们能放入物品2,因此我们现在有两种选择:第一种就是不放物品2,那么我们就只能放物品1,所以我们能获得的最大收益就等于在此背包容量下放入物品1的最大收益;第二种就是放物品2,因为我们已经放了物品2了,只剩一个物品1了,所以此时的最大收益就等于物品2的价值 + 背包剩余容量下放入物品1的最大收益。我们要取这两种情况中收益最大的方案

填表过程如下图所示:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

接着我们又考虑编号为3的物品在背包容量为 1 ~ 8 的情况下,我们能获取到的最大利益为多少。

首先知道物品3的重量为4,因此在背包容量小于4时,我们无法放入物品3,那么我们还需要考虑的就有物品1和物品2,从上一步骤得知,物品2的最大收益时在考虑了物品1的基础上得出的,因此我们只需要考虑放入物品2的最大收益即可,那么此时的最大收益就等于在当前背包容量下,放入物品2的最大收益;

当背包容量大于等于4时,我们能放入物品4,与上一个步骤类似,我们有两种选择,即放物品3和不放物品3

填表结果如下图所示:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

同理,最后一行的填表过程如下图所示:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

最终的填表结果如下图所示:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

在表中可以很明显地看到,我们在背包容量为8的情况下,能获取到的最大收益为15

此时,我们还需要倒着推回去,判断一下是拿了哪几样物品才获取到的最大收益

首先找到最大收益对应的格子为物品4,然后我们判断一下该收益是否等于前一种物品(物品3)的最大收益,若等于,则表示没有放入物品4;否则表示放入了物品4。

为什么会这样判断呢?因为我们说过,在判断一个物品在某背包容量下的最大收益时,当物品重量大于背包容量或者我们选择不放入该物品时,此时的最大收益就等于前一种物品在此背包容量下的最大收益

所以这里能判断,我们放入了物品4,则此时背包容量只剩 8 - 5 = 3,所以我们找到物品3在背包容量等于3情况下最大收益对应的格子,同样判断一下上一种物品(物品2)的最大收益是否等于此格子中的最大收益,当前判断为相等,因此我们没有放入物品3

当前背包容量仍为3,我们找到物品2在背包容量等于3情况下最大收益对应的格子,判断当前最大收益不等于上一种物品(物品1)在背包容量为3情况下的最大收益,因此我们放入了物品2

则此时背包容量为 3 - 3 = 0了,无法再放入任何物品了,所以我们就可以得出结论,我们在放入物品2和物品4的情况下收益最大,最大收益价值为15


上面讲解了背包问题的动态规划思路,下面我们用代码来实现一下

function knapsack(capacity, size, value, n) {

// 返回较大的值

function max(v1, v2) {

return v1 > v2 ? v1 : v2

}

let table = []

// 生成长度为n的表

for(let i = 0; i <= n; i++) {

table[i] = []

}

// 判断每种物品面对不同背包容量时的最大收益

for(let i = 0; i <= n; i++) {

for(let j = 0; j <= capacity; j++) {

// 物品种类序列为0或者背包容量为0时,最大收益为0

if(i == 0 || j == 0) table[i][j] = 0;

// 背包容量小于物品重量时,最大收益等于上一种物品在此背包容量下的最大收益

else if(size[i - 1] > j) {

table[i][j] = table[i - 1][j]

}

/* 背包容量大于物品重量时,最大收益分两种情况:

第一种情况:不放此物品。则最大收益等于上一种物品在此背包容量下的最大收益;

第二种情况:放此物品。则最大收益等于该物品的收益加上剩余背包容量下,上一种物品的最大收益

*/

else {

table[i][j] = max(table[i - 1][j], value[i - 1] + table[i - 1][j - size[i - 1]])

}

}

}

// 最大收益值

let max_value = 0

let which = -1

// 寻找在背包容量为capacity时的最大收益值,以及最大收益值所对应的物品种类

for(let i in table) {

let k = table[i][capacity]

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法
【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法
【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法
【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

ES6

  • 列举常用的ES6特性:

  • 箭头函数需要注意哪些地方?

  • let、const、var

  • 拓展:var方式定义的变量有什么样的bug?

  • Set数据结构

  • 拓展:数组去重的方法

  • 箭头函数this的指向。

  • 手写ES6 class继承。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

微信小程序

  • 简单描述一下微信小程序的相关文件类型?

  • 你是怎么封装微信小程序的数据请求?

  • 有哪些参数传值的方法?

  • 你使用过哪些方法,来提高微信小程序的应用速度?

  • 小程序和原生App哪个好?

  • 简述微信小程序原理?

  • 分析微信小程序的优劣势

  • 怎么解决小程序的异步请求问题?

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

其他知识点面试

  • webpack的原理

  • webpack的loader和plugin的区别?

  • 怎么使用webpack对项目进行优化?

  • 防抖、节流

  • 浏览器的缓存机制

  • 描述一下二叉树, 并说明二叉树的几种遍历方式?

  • 项目类问题

  • 笔试编程题:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

最后

信小程序的数据请求?

  • 有哪些参数传值的方法?

  • 你使用过哪些方法,来提高微信小程序的应用速度?

  • 小程序和原生App哪个好?

  • 简述微信小程序原理?

  • 分析微信小程序的优劣势

  • 怎么解决小程序的异步请求问题?

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

其他知识点面试

  • webpack的原理

  • webpack的loader和plugin的区别?

  • 怎么使用webpack对项目进行优化?

  • 防抖、节流

  • 浏览器的缓存机制

  • 描述一下二叉树, 并说明二叉树的几种遍历方式?

  • 项目类问题

  • 笔试编程题:

【数据结构与算法】三个经典案例带你了解动态规划,前端程序员,动态规划,算法

最后

技术栈比较搭,基本用过的东西都是一模一样的。快手终面喜欢问智力题,校招也是终面问智力题,大家要准备一下一些经典智力题。如果排列组合、概率论这些基础忘了,建议回去补一下。文章来源地址https://www.toymoban.com/news/detail-845406.html

到了这里,关于【数据结构与算法】三个经典案例带你了解动态规划的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【机器学习】最经典案例:房价预测(完整流程:数据分析及处理、模型选择及微调)

    【机器学习】最经典案例:房价预测(完整流程:数据分析及处理、模型选择及微调)

    环境:anaconda+jupyter notebook 首先要明白一点: 数据决定模型的上限!数据决定模型的上限!数据决定模型的上限! (重要的事情说三遍。)对于数据的处理在一个完整案例中花费精力的比重应该占到一半以上。 以下分为:数据分析、数据清洗两部分。 数据分析主要包括:查

    2024年02月05日
    浏览(12)
  • 第六篇【传奇开心果系列】Python的自动化办公库技术点案例示例:大学生数据全方位分析挖掘经典案例

    第六篇【传奇开心果系列】Python的自动化办公库技术点案例示例:大学生数据全方位分析挖掘经典案例

    Pandas在大学生数据的分析和挖掘中发挥着重要作用,帮助研究人员和教育工作者更好地理解大学生群体、优化教学管理和提升教育质量。 Pandas库可以用来分析挖掘大学生数据的各各方面,包括但不限于: 学生成绩数据:可以通过Pandas对大学生的成绩数据进行统计分析、可视

    2024年03月15日
    浏览(19)
  • Hadoop系统应用之MapReduce相关操作【IDEA版】---经典案例“倒排索引、数据去重、TopN”

    Hadoop系统应用之MapReduce相关操作【IDEA版】---经典案例“倒排索引、数据去重、TopN”

      倒排索引是文档检索系统中最常用的数据结构,被广泛应用于全文搜索引擎。倒排索引主要用来存储某个单词(或词组)在一组文档中的存储位置的映射,提供了可以根据内容来查找文档的方式,而不是根据文档来确定内容,因此称为倒排索引(Inverted Index)。带有倒排索引

    2024年02月07日
    浏览(14)
  • 数据结构(五)数据结构与算法中的经典题

    本文是在原本数据结构与算法闯关的基础上总结得来,加入了自己的理解和部分习题讲解。至此数据结构介绍已完结,后续会把数据结构算法题系列更完。 原活动链接 邀请码: JL57F5 根据要求完成题目 Q1. (单选)以下哪些数据结构支持随机访问? A. 数组 B. 单链表 C. 双向链表

    2024年01月20日
    浏览(11)
  • 【深度学习时间序列预测案例】零基础入门经典深度学习时间序列预测项目实战(附代码+数据集+原理介绍)

    【深度学习时间序列预测案例】零基础入门经典深度学习时间序列预测项目实战(附代码+数据集+原理介绍)

    🚨注意🚨 :最近经粉丝反馈,发现有些订阅者将此专栏内容进行二次售卖,特在此声明,本专栏内容仅供学习,不得以任何方式进行售卖,未经作者许可不得对本专栏内容行使发表权、署名权、修改权、发行权、转卖权、信息网络传播权,如有违者,追究其法律责任。 👑

    2023年04月15日
    浏览(15)
  • 【数据结构与算法】十大经典排序算法-希尔排序

    【数据结构与算法】十大经典排序算法-希尔排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 希尔排序是一种插入排序的改进版本,旨在解决插入排序在处理大规模数据时的效率问题。通过将数组分为多个子序列并对

    2024年02月12日
    浏览(16)
  • 【数据结构与算法】十大经典排序算法-冒泡排序

    【数据结构与算法】十大经典排序算法-冒泡排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌴 掘金 :HelloCode 🌞 知乎 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复地交换相邻元素的位置来将最大(或最小)的元素逐步“冒泡”到

    2024年02月14日
    浏览(11)
  • 【数据结构与算法】之多指针算法经典问题

    【数据结构与算法】之多指针算法经典问题

    本文为 【数据结构与算法】多指针算法经典问题 相关介绍,下边将对 链表反转 (包含 迭代反转链表 、 递归反转 、 头插法反转 ), 双指针-快慢指针 (包含 寻找单向无环链表的中点 、 判断单向链表是否有环及找环入口 ), 双指针-左右指针 (包含 两数之和 、 二分查

    2024年02月03日
    浏览(11)
  • 【数据结构与算法】十大经典排序算法-快速排序

    【数据结构与算法】十大经典排序算法-快速排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 快速排序(Quick Sort)是一种高效的排序算法,是对冒泡排序的优化。它采用分治法(Divide and Conquer)的思想,将待排序序列

    2024年02月13日
    浏览(15)
  • 【数据结构与算法】十大经典排序算法-插入排序

    【数据结构与算法】十大经典排序算法-插入排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 插入排序(Insertion Sort)是一种简单直观的排序算法,其基本思想是将一个记录插入到已排好序的有序序列中,直到所有记录

    2024年02月13日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包