您的位置:首页 > 编程语言 > C语言/C++

【Decode Ways】cpp

2015-06-04 14:49 330 查看
题目:

A message containing letters from
A-Z
is being encoded to numbers using the following mapping:

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

Given an encoded message containing digits, determine the total number of ways to decode it.

For example,
Given encoded message
"12"
, it could be decoded as
"AB"
(1 2) or
"L"
(12).

The number of ways decoding
"12"
is 2.

代码:

class Solution {
public:
int numDecodings(string s) {
if (s.empty()) return 0;
if (s[0]=='0') return 0;
const int n = s.size();
vector<int> dp(n+1, 0);
dp[0] = dp[1] = 1;
for ( int i=2; i<=n; ++i )
{
if ( s[i-1]=='0' )
{
if ( s[i-2]=='0' || s[i-2]>'2')
{
return 0;
}
else
{
dp[i] = dp[i-2];
}
continue;
}
if ( s[i-2]=='0' || (s[i-2]-'0')*10+s[i-1]-'0'>26 )
{
dp[i] = dp[i-1];
}
else
{
dp[i] = dp[i-1] + dp[i-2];
}
}
// for ( int i=0; i<dp.size(); ++i ){ cout << dp[i] << " "; }
// cout << endl;
return dp
;
}
};


tips:

第一眼看到这道题是hard,AC率只有16%就觉得此题得非常困难;至少也得是个二维dp。结果就把自己给蒙住了。

就是常规思路,按照一维dp的路子往后走,当前元素可以自己单独解码或者跟前一个元素合起来被解码。

corner cases的核心在于两点:

1. 遇上0怎么办

2. 是否和大于26

基于这两个点,扫两次corner case就通过了。

上述的代码条件判断可以合并一些,但是为了保留原始思考痕迹,就保留原样了。

============================================

第二次过这道题,dp[0]=1一开始写成了dp[0]=0。

class Solution {
public:
int numDecodings(string s) {
if ( s.empty() ) return 0;
int dp[s.size()+1];
fill_n(&dp[0], s.size()+1, 0);
if ( s[0]=='0' ) return 0;
dp[0] = 1;
dp[1] = 1;
for ( int i=2; i<=s.size(); ++i )
{
if ( s[i-1]=='0' )
{
if ( s[i-2]=='0' || s[i-2]>'2' ){
return 0;
}
else{
dp[i] = dp[i-2];
}
continue;
}
if ( s[i-2]=='0' || (s[i-2]-'0')*10+(s[i-1]-'0')>26 )
{
dp[i] = dp[i-1];
}
else
{
dp[i] = dp[i-1]+dp[i-2];
}
}
return dp[s.size()];

}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: