460 字
2 分钟
动态规划的那些题
动态规划
1 将数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是”bccfi”, “bwfi”, “bczi”, “mcfi”和”mzi”
// 主要就是判断最后两个数字是否在10-25之间var translateNum = function(num) { var num_str = num.toString() var n = num_str.length var d = [1] d[-1] = 1 for(let i=1;i<n;i++){ let dig = +num_str.substr(i-1,2) if(dig >= 10 && dig <=25){ d[i] = d[i-1] + d[i-2] }else{ d[i] = d[i-1] } } return d[n-1]}2 最长重复子数组
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出: 3 解释: 长度最长的公共子数组是 [3, 2, 1]
状态转移方程 dp[i][j] = dp[i-1][j-1] + 1
const findLength = (A, B) => { const m = A.length; const n = B.length; const dp = Array.from(Array(n+1),()=>Array(n+1).fill(0)) let res = 0; for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { if (A[i - 1] == B[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } res = Math.max(dp[i][j], res); } } return res;}3 交错字符串
给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac” 输出: true
输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbbaccc” 输出: false
f[i][j] |= f[i-1][j] && s2[i-1] === s3[p]
var isInterleave = function(s1, s2, s3) { let n1 = s1.length let n2 = s2.length let n3 = s3.length if(n1+n2 !== n3){ return false }
let f = new Array(n2+1) for(let i=0;i<n2+1;i++){ f[i] = [] } f[0][0] = true
for(let i=0;i<n2+1;i++){ for(let j=0;j<n1+1;j++){ let p = i+j-1 if(i>0){ f[i][j] |= f[i-1][j] && s2[i-1] === s3[p] } if(j>0){ f[i][j] |= f[i][j-1] && s1[j-1] === s3[p] } } } return f[n2][n1]}