目录
动态规划
JS构建二维数组注意
题目
连续子数组的最大和
原题链接
解析
核心思想
答案
丑数
原题链接
解析
核心思想
答案
n个骰子的点数
原题链接
解析
核心思想
答案
通常用于优化递归或求最大、最小值等问题。一般把结果存在一个数组中.
首先确定初始值res[0]=f(0),然后找到上下层res[i]和res[i+1]的关系,通过for循环递归解出arr[n]的值,找上下层关系的时候可以去列举res[0],res[1],res[2]...列举初始的前几位,找到对应的关系。
需要注意
JavaScript构建2维数组的时候需要谨慎使用fill和map函数。正确的构建5*5全为0的数组使用
new Array(5).fill(0).map(v=>new Array(5).fill(0))。
错误的构建方式
1.使用new Array(5).map(v=>new Array(5).fill(0))相当于new Array(5),因为map不会对值为empty的数值返回内容。
2.new Array(5).fill(new Array(5).fill(0)),此时的arr[0]和arr[1~4]都是指向相同的引用,也就是说改变数组中一个值,其余4个值都会变为相同的,即fill填充的如果不是基础值,填充的会是相同的引用。
输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
输入:[1,-2,3,10,-4,7,2,-5]
返回值:18
经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18
输入:[2]
返回值:2
输入:[-10]
返回值:-10
连续子数组的最大和_牛客题霸_牛客网
这里需要注意要有一个变量存储,之前一个最大连续的子数组一直加上到i位元素的和。例如输入[1,-2,3,10,-4,7,2,-5]时,当计算到-4时,计算是否加上7时,该变量应该存储3+10+-4,这时用3+10+-4+7和3+10和7这3位对比选取最大。
首先找到初始值res[0]=arr[0],然后找到上下层级的关系。这里需要分析以下例如下面3个数组,[-1,100],[-10,100,40,80,-20,200]、[-1,-10],我们什么时候需要把下一个算进去,什么时候需要重新开始计算。
结论:res[i+1]=Math.max(res[i],tmp+arr[i+1],arr[i+1],) tmp为记录之前的一个最大连续子数组一直加上到目前i位元素的和。
function FindGreatestSumOfSubArray(array) {
let temp = array[0]
let res = new Array(array.length).fill(0)
res[0] = array[0]
for (let i = 1; i < array.length; i++) {
temp = Math.max(array[i], array[i] + temp)
res[i] = Math.max(temp, res[i - 1])
}
return res.pop()
}
我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。
示例:
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12
是前 10 个丑数。
说明:
1
是丑数。var nthUglyNumber = function(n) {
};
力扣
注意题目要求要只能被2,3,5整除,14被2整除后是7,不算。
最小堆的解法见原题链接。
假如res[n]表示第n为丑数,因为只能被2,3,5整除,那么res[n]必然为2*res[m]或者3*res[m]或者5*res[m]其中一个,此时便可以用动态规划,
初始值,res[1]=1,
找上下层的关系res[2]=Math.min(res[1]*2,res[1]*3,res[1]*5)
res[3]=Math.min(res[2]*2,res[1]*3,res[1]*5)
总结:res[n]=Math.min( res[p2] * 2, res[p3] * 3, res[p5] * 5),p2,p3,p5每次取完后需要递增。
var nthUglyNumber = function(n) {
const res = new Array(n + 1).fill(0);
res[1] = 1;
let p2 = 1, p3 = 1, p5 = 1;
for (let i = 2; i <= n; i++) {
const num2 = res[p2] * 2, num3 = res[p3] * 3, num5 = res[p5] * 5;
res[i] = Math.min(num2, num3, num5);
if (res[i] === num2) {
p2++;
}
if (res[i] === num3) {
p3++;
}
if (res[i] === num5) {
p5++;
}
}
return res[n];
};
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
示例 1:
输入: 1 输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]
示例 2:
输入: 2 输出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]
var dicesProbability = function(n) {
};
力扣
思考骰子的添加对点数概率的影响。
1个骰子时,每个点数的组合数为[1,1,1,1,1,1],概率在组合数上除以6,添加一个骰子,点数为2~12,每个点数的组合数为少一个骰子的组合数加1~6,例如点数5为1+4,2+3,3+2,4+1,即组合数的和为4。得出所有组合数为[1,2,3,4,5,6,5,4,3,2,1],概率为除以6*6,再加一个骰子,点数为3~18,每个点数的组合数为少一个骰子的组合数加1~6。
[1,2,3,4,5,6,5,4,3,2,1]
[1,2,3,4,5,6,5,4,3,2,1]
[1,2,3,4,5,6,5,4,3,2,1]
[1,2,3,4,5,6,5,4,3,2,1]
[1,2,3,4,5,6,5,4,3,2,1]
[1,2,3,4,5,6,5,4,3,2,1]
=[1,3,6,10,15,21,25,27,27,25,21,15,10,6,3,1]
以此类推。
function nums(n){
if(n===1){
return [1,1,1,1,1,1]
}else {
let arr = nums(n-1), re =Array(5*n+1).fill(0);
for(let i=0;i<6;i++){
for(let j=0;jitem/(6**n));
};