DFS求解DecodeWays输出所有情况和方法数

来源:互联网 发布:java 1603 编辑:程序博客网 时间:2024/05/21 04:52

这是一道leetcode上的原题,在笔试面试中也经常遇到。一般我们只要求出所有的解码种类数目就可,并没有要求输出所有的解码序列,这里运用DFS解决了这个问题。题目描述如下:
这里写图片描述
现在我们先求解一下编码方法数。通过题目我们可以知道,编码是通过一个或两个字符来实现,对于一个编码“12125”;可以一个一个字符的进行编码,也可以两个来进行,这就类似于我们的爬楼梯问题,一次可以上一个台阶,一次也可以上两个台阶,求所有的方式,何其相似。因此我们也可以运用动态规划来求解本题,只是要加上一些条件判断。一个字符是如果是‘0’,那么不能解码,就依赖于他前一个字符看看能否组成10-26之间的数进行解码,因此对于从0-n位置的字符,他的方法数为f(n)=f(n-1)+f(n-2);即对n位置,他可以选择自己单独解码,也可选择与前面一起解码。具体代码如下:

int numDecodings(string &s){    int len = s.size();    if( (len <= 0)|| (len>0&&s[0]=='0'))        return 0;    int *dp_num = new int[len]{};    dp_num[0] = 1;    for (int i = 1; i < len; i++)    {        dp_num[i] = s[i] == '0' ? 0 : dp_num[i - 1];//选取i这一位,只取当前指向的一个数字,如果为0,dp[i-1]=0,否则,取dp[i-1]        if (i >= 1 && (s[i - 1] == '1' || (s[i - 1] == '2'&&s[i] <= '6')))//当前数和当前数的前一个数,看看是否在10-26之间        {            if (i == 1)                dp_num[i] += 1;            else                dp_num[i] += dp_num[i - 2];        }    }    return dp_num[len - 1];}

当然如果要输出所有的解码方式具体是怎么样,可以进行DFS,比如12125,我们选择1这个字符解码,也可以选择12进行解码,之后2125或125相当于是一个新的字符要进行解码,不断进行搜素,终止条件为到达字符串尾。代码如下:

/*s表示原始字符串,用引用,通过下标可以获取到字符temp 用来存储解析好的字符串,最后输出,用引用,一直记录解码后的字符,直至递归返回start表示从第几个位置的字符开始解析end表示s.size();*/void numDecodings_list(string &s,string &temp,int start,int end){    int len = s.size();    if (len <= 0 || (len > 0 && s[start] == '0'))        return ;    if (start == end)    {        num++;        cout <<"第"<<num<<"种解码为:"<< temp << endl;        //temp.clear();不用清除,递归后pop后自己会变为空        return;    }    if (s[start] != '0')//第一个不为0    {        char a = s[start] - '1' + 'a';        temp.push_back(a);        numDecodings_list(s, temp, start + 1, end);//继续递归搜索        temp.pop_back();//再回到第一次调用处,这里弹出后 temp=""为空,可以继续添加        if (start+1<end&&(s[start] == '1' || (s[start] == '2'&&s[start + 1] <= '6')))//注意start+1<end        {                   a = (s[start] - '0') * 10 + (s[start + 1] - '1') + 'a';            temp.push_back(a);            numDecodings_list(s, temp, start +2, end);//继续递归搜索            temp.pop_back();        }    }}int main(void){    string s;    string t;    while (1)    {        cin >> s;        numDecodings_list(s, t, 0, s.size());        t.clear();        num = 0;//全局    }}

输出如下:
这里写图片描述

阅读全文
0 0