周日休息,为了保持一下手感,在牛客找一两道题目做做
这是一道动态规划 / 回溯法题目,由于只是问当前规则下的译码总数,而并不需要给出所有的可能结果,用动态规划应该是可以尝试的方向
先给回溯法,主要是需要注意一下取0,和两位数十位为0的情况,这是有错误的分配,应该全部避开,同时,在终止条件外的代码块还有越界的可能,这里也是需要考虑到边界情况。
class Solution {
public:
/**
* 解码
* @param nums string字符串 数字串
* @return int整型
*/
int res;
vector<bool> visitVec;
int chooseList[2] = {0,1};
void resInit(string & nums){
res = 0;
for(int i = 0;i< nums.size();i++){
visitVec.push_back(false);
}
}
bool isValid(int offerset,int indexBase,string & nums){
int dataCheck = 0;
if(nums[indexBase] == '0'){
return false;
}
if(offerset == 0){
dataCheck += int(nums[indexBase] - '0');
}else{
if(indexBase+offerset > nums.size()-1){return false;}
dataCheck += int(nums[indexBase] - '0') * 10;
dataCheck += int(nums[indexBase+offerset] - '0') ;
}
if(dataCheck > 0 && dataCheck <= 26){
return true;
}
return false;
}
void traceback(vector<bool> &visitVec, int *chooseList,int chooseNum,string & nums){
if(visitVec[chooseNum] ){
return;
}
if(chooseNum > nums.size()-1){
res++;
return;
}
for(int i = 0;i< 2;i++){
if(!isValid(chooseList[i],chooseNum,nums)){
continue;
}
visitVec[chooseNum] = true;
visitVec[chooseNum+chooseList[i]] = true;
traceback(visitVec, chooseList, chooseNum+chooseList[i]+1, nums);
visitVec[chooseNum] = false;
visitVec[chooseNum+chooseList[i]] = false;
}
}
int solve(string nums) {
// write code here
resInit(nums);
traceback(visitVec, chooseList, 0, nums);
return res;
}
};
动态规划今晚一定补上(ಥ﹏ಥ)
待续。。。
来咯来咯
动态规划:
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 解码
* @param nums string字符串 数字串
* @return int整型
*/
int solve(string nums) {
// write code here
vector<int> dp(nums.size(),0);
//状态:从主问题到子问题变化的量 已译码的序列尾部索引 i
//dp[i]含义 : 以索引为i的数字为结尾的序列对应的译码结果
//base case : dp[0] = 1
//递推关系: dp[n] = (dp[n-1]) + (dp[n-2])
//离以n为结尾的序列只剩下最后一个字符时,和剩下两个字符时的两种情况
//base case
if((int)(nums[0] - '0') >= 1 && (int)(nums[0] - '0') <=9 ){
dp[0] = 1;
}
if((int)(nums[1] - '0') >= 1 && (int)(nums[1] - '0') <=9 ){
dp[1] = 1;
}
if( (int)(nums[0] - '0') * 10 + (int)(nums[1]- '0') >= 10 && (int)(nums[0] - '0') * 10 + (int)(nums[1]- '0') <= 26){
dp[1] = ((int)(nums[1]- '0') == 0) ? 1: 2;
}
//遍历状态
for(int i = 2;i < nums.size();i++){
int sigleNum = (int)(nums[i] - '0');
if(i - 1 >= 0 && sigleNum > 0 && sigleNum <= 9 ){
dp[i] += dp[i-1];
}
int twistNum = (int)(nums[i-1] - '0') * 10 + (int)(nums[i]- '0');
if(i - 2 >= 0 && twistNum >= 10 && twistNum <= 26 ) {
dp[i] += dp[i-2];
}
}
return dp[nums.size()-1];
}
};