3.27网易互联网笔试动态规划题解-类比剑指
题目描述:(第二题)
给一个小写字母字符串。
可以标记的条件:相邻两个字母为相同字母,或者是字母表中的相邻字母,例如“aa” "ba" "st"可以被标记,"ad" 不可以被标记
a为1分,b为2分,以此类推
一个字母只能被标记一次。求最高分数。
输入:abb 输出:4
输入:abgcc 输出:a1+b2+c3+c3 = 6
思路:动态规划:
map 映射 字母与序号的关系。dp[i] 表示以 i 结尾的最大分数
- 当
s[i]和s[i-1]不相邻dp[i] = dp[i-1] - 当
s[i]和s[i-1]相邻
要么取倒数两位,要么取之前的不变dp[i] = Math.max(dp[i],dp[i-2]+map.get(s[i-1])+map.get(s[i-2])
注意:考虑动态规划,只需要依次动归,不需要太复杂地考虑条件了
主动使用 Math.max 方法呀。
// 哈希表
let map = new Map([["a",1],["b",2],....["z",26]]);
// 判断两个字符是否字母表相邻
function closed(i,j){
return Math.abs(map.get(i)-map.get(j))<=1;
}
function maxClosed(s){
if(s.length<=1) return 0;
let dp=[];
dp[0] = 0;
if(closed(s[0],s[1])){//前两位相邻
dp[1] = map.get(s[0]) + map.get(s[1]);
}else{// 前两位不相邻
dp[1] = 0;
}
for(let i=2;i<s.length;i++){
if(closed(s[i],s[i-1])){// i-1和i是相邻字符
dp[i] = Math.max(dp[i-1],dp[i-2]+map.get(s[i-1])+map.get(s[i-2]))
}else{// i-1和i不是相邻字符
dp[i] = dp[i-1]
}
}
} 剑指 Offer 46. 把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法dp[i] 以 i 结尾的翻译方法数。
s[i]+s[i-1]属于[10, 25]
把最后一个数字当做一个字母翻译:dp[i] = dp[i-1]s[i]+s[i-1]不属于[10, 25]
25—>z 或者 cf
可以把最后2个数字当做2个字母翻译 + 也可以把最后2个数字当做一个字母翻译:dp[i] = dp[i-1] + dp[i-2]
var translateNum = function(num) {
if(num<=1) return 1;
let s = num+"";
let dp = [];
dp[0] = 1;
// 初始化 dp 列表
if((s[0]+s[1])*1>=10&&(s[0]+s[1])*1<=25){
dp[1] = 2;
}else{
dp[1] = 1;
}
// 动态规划
for(let i=2;i<s.length;i++){
if((s[i-1]+s[i])*1>=10&&(s[i-1]+s[i])*1<=25){
dp[i] = dp[i-1] + dp[i-2]
}else{
dp[i] = dp[i-1];
}
}
return dp[dp.length-1];
}; #网易笔试##实习##笔试题目#


