长沙前端培训班分享:不重复的组成4位数求平均值。解决方案应用了动态规划的算法思想,下面我们一起来看看什么是动态规划吧。
一、动态规划动态规划的定义 动态规划(dynamic programming)是运筹学的一个分支,20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decisions)的优化问题时,提出了著名的最优化原理,把多阶段过程转化为-系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法-动态规划。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。
这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用动态规划的步骤寻找最优子结构(状态表示)归纳状态转移方程边界初始化二、解决方案思考过程 求所有四位数的平均值,我可以把问题缩小,先把四位数的所有组合找出来 想一想,求四位数的所有组合,如果我已知三位数的所有组合,能不能帮助我更快求出四位数的所有组合。 如果这里问题不是所有四位数,是六数位或者更多,我能用同样的函数得到答案吗 状态转移方程当我们知道三位数的所有组合,就能利用规律求出四位数的所有组合,那么现在只需要求出三位数的所有组合了;求出两位数的所有组合,就可以利用规律求出三位数的所有组合;求出一位数的所有组合,再利用规律求出两位数的所有组合。那这里问题就被分解成了两个 1. 一位数的所有组合是什么 2. 这个规律是什么第一个问题,相信所有人很快就能得到答案,“3”的所有组合就是[3],“1”的所有组合就是[1]。
第二个问题,我们来想一下思路 当问题是求出“1”所有组合,刚刚求出了答案是[1] 当问题是求出“1,3“所有组合时: 我们可以在[1]的左边插入3,可以在[1]的右边插入3,结果是[13,31]当问题是求出“1,3,5”的所有组合我们可以在“1,3”所有组合的基础上来求,“13”的左边、中间、右边插入5,那么结果有[513,153,135],“31”的左边、中间、右边插入5,所有结果是[531,351,315],那么“1,3,5”这三个数的所有组合是[513,153,135,531,351,315]。到这里,我已经发现了规律,我要求“1350”这四位数的所有组合,我只需要求出”135“这三个数的所有组合,然后再对其每个数的每个位置插入新的数(0)即可找打所有的四位数组合了写代码let arr = [1, 3, 5,0]
console.log(main(arr))
// 主方法入口
function main(arr) {
let allValue = [];
for (let r of arr) {
allValue = insert(allValue, r)
// 输出一下 每一次都会输出当前结果
console.log(allValue)
}
// 最后计算平均数
// 加起来的数
let sum = 0
for (let num of allValue) {
sum += parseInt(num)
}
return sum / allValue.length;
}
/**
* allArr 表示插入的集合 是一个数组 表示之前已经计算出的数组合计
* insertValue表示当前插入的值
* insert([],1) // ['1']
* insert(['1'], 3) // ['31','13']
* insert(['13','31'], 5) // ['531', '351', '315', '513', '153', '135']
*/
function insert(allArr, insertValue) {
// 特殊处理为空情况
if (allArr.length == 0) return [insertValue + '']
let result = []
for (let nowValue of allArr) {
// 进行插入操作 重点 i<=nowValue.length 是可以在末尾也插入值 实际循环比nowValue的长度多一次
for (let i = 0; i <= nowValue.length; i++) {
result.push(insertStr(nowValue, i, insertValue))
}
}
return result
}
/**
* 字符串插入
* source 原字符串
* start表示插入位置
* newStr 表示插入新的字符串
* insertStr('1234',0,'5') // 51234
* insertStr('1234',3,'5') // 12354
* insertStr('1234',4,'5') // 12345
*/
function insertStr(source, start, newStr) {
return source.slice(0, start) + newStr + source.slice(start);
}
相关文章
06.29抢座
了解千锋动态
关注千锋教育服务号
扫一扫快速进入
千锋移动端页面
扫码匿名提建议
直达CEO信箱