LeetCode-91-解码方法

题目

一条包含字母 A-Z 的消息通过以下方式进行了编码:

'A' -> 1 'B' -> 2 ... 'Z' -> 26

给定一个只包含数字的非空字符串,请计算解码方法的总数。

示例 1:

输入: "12" 输出: 2 解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。

示例 2:

输入: "226" 输出: 3 解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

思路

按照动态规划的思路,可以很容易得到状态转移方程:dp[n] = dp[n-1] + dp[n-2];

但是这道题的难点在于其中的诸多限制,特别是数字0造成的限制:

  1. 当前数字和上一个数字都为0时, dp[n] = 0;

  2. 当前数字为0,上一个数字不为0,且组合小于26时,dp[n] = dp[n-2]

  3. 当前数字为0,上一个数组不为0,且组合大于26时,dp[n] =0

  4. 当前数字不为0,上一个数字为0,dp[n] = dp[n-1]

  5. 当前数字不为0,上一个数字不为0,组合数字小于26时,dp[i] =dp[i-1]+dp[i-2]

  6. 当前数字不为0,上一个数字不为0,组合数字大于26时,dp[i]=dp[i-1]

     

思路比较混乱,所以代码就有点冗余,可以做进一步的优化,但是运行之后效果出奇的好,双百分百:

执行用时 :0 ms, 在所有 C 提交中击败了100.00% 的用户

内存消耗 :5.2 MB, 在所有 C 提交中击败了100.00%的用户

那就不改动了,代码如下:

代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>



int numDecodings(char * s){
int len = strlen(s);
int dp[4000] = {0};
int i = -1;

if (len==0) return 0;
if (len==1)
{
if ('0' == *s) return 0;
return 1;
}

// 设置初始条件

if (s[0]!='0')
{
dp[0] = 1;
dp[1] = 1;
}

// dp[n] = dp[n-1] + dp[n-2]
for (i=2; i<len+1; i++)
{
int m = s[i-2] - 48, n = s[i-1] - 48;
//printf ("%d %d\n", m, n);

if (n==0 && m==0)
{
dp[i] = 0;
}else if (n==0 && m != 0)
{
if (m*10+n <= 26)
{
dp[i] = dp[i-2];
}else
{
dp[i] = 0;
}
}else if (n!=0 && m==0)
{
dp[i] = dp[i-1];
}else
{
if (m*10+n <= 26)
{
dp[i] = dp[i-1] + dp[i-2];
}else
{
dp[i] = dp[i-1];
}
}



}
return dp[len];
}



posted @ 2020-03-28 17:32  樱花小猪  阅读(282)  评论(0编辑  收藏  举报