有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。
现在给一串数字,返回有多少种可能的译码结果
数据范围:字符串长度满足
进阶:空间复杂度 ,时间复杂度
有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。
"12"
2
2种可能的译码结果(”ab” 或”l”)
"31717126241541717"
192
192种可能的译码结果
public class Solution { int res = 0; public int solve (String nums) { // write code here //dp int len = nums.length(); if (len == 0 || nums.charAt(0) == '0') return 0; int[] dp = new int[len+1]; dp[0] = 1; for (int i=1;i<=len;++i){ char c = nums.charAt(i-1); if (c != '0'){ dp[i] = dp[i-1]; } if (i-2 >= 0){ int val = Integer.valueOf(nums.substring(i-2, i)); if (val >=10 && val <= 26){ dp[i] += dp[i-2]; } } } return dp[len]; /*dfs(nums,0); return res;*/ // dfs /* private void dfs(String nums, int start) { if(start >= nums.length()) { res++; return; } if(Integer.valueOf(nums.substring(start, start+1)) != 0) dfs(nums,start+1); if(start < nums.length()-1 && Integer.valueOf(nums.substring(start, start+2)) >= 10 && Integer.valueOf(nums.substring(start, start+2)) <= 26) dfs(nums,start+2);*/ } }
class Solution { public: /** * 解码 * @param nums string字符串 数字串 * @return int整型 */ int solve(string nums) { // write code here string s=nums; int n=s.size(); vector<int> dp(n+1, 0); bool flag=true; dp[1] = s[0]=='0'?0:1; for(int i=2; i<=n; i++) { if(s[i-1]=='0' && s[i-2]=='0') { flag = false; break; } if(s[i-1]=='0') dp[i] = i-2>0?dp[i-2]:1; else if(s[i-2]=='0') dp[i] = dp[i-1]; else { dp[i] += dp[i-1]; if(s[i-2]=='1' || (s[i-2]=='2' && s[i-1]<='6' && s[i-1]>='1')) dp[i] += i-2>0?dp[i-2]:1; } } return flag?dp[n]:0; } };
import java.util.*; public class Solution { public int solve (String nums) { //dp[i]: 以第i个字符结尾的子串有几种译码结果 int[] dp = new int[nums.length() + 1]; dp[0] = 1; dp[1] = nums.charAt(0) == '0' ? 0 : 1; //第一个字符 for(int i = 2; i<=nums.length(); i++){ char pre = nums.charAt(i-2), cur = nums.charAt(i-1); //('1~2' + '0') || ('2' + '7~9') || ('3~9' + '1~9') dp[i] = dp[i-1]; if(cur == '0'){ //('3~9' + '0') || '00' if(cur == '0' && pre != '1' && pre != '2'){ return 0; } }else{ //('1' + '1~9') || ('2' + '1~6') if(pre == '2' && cur <= '6' || pre == '1'){ dp[i] = dp[i-1] + dp[i-2]; } } } return dp[nums.length()]; } }
public class Solution { /** * 解码 * @param nums string字符串 数字串 * @return int整型 */ public int solve (String nums) { // 带条件的青蛙跳台阶 // 如果n位数和n-1位的数字组合而成的2位数在10-26闭区间中,f(n)=f(n-1)+f(n-2); // 否则f(n)=f(n-1) // 注意,有几个题干没说清楚的点在此补充: // 0+个位数不能当个位数来使,比如1102只能拆成1/10/2不能拆成11/02 // 不能出现孤立0在末位的情况,比如100不能当成10/0处理,但010可以当成0/10处理 // 字符串“0”算作0种译法 if(nums.length()==0 || "0".equals(nums)){ return 0; } int a = 1; int b = 1; int sum = 1; for(int i=1;i<nums.length();i++){ // 计算和前一个数组成2位数的值 int value = getValue(nums.charAt(i-1),nums.charAt(i)); // 很重要的一步操作 if(nums.charAt(i) == '0') b = 0; // 带条件的青蛙跳台阶 if(value>=10 && value <=26){ sum = a + b; } else{ sum = b; } a = b; b = sum; } return sum; } public int getValue(char a, char b){ return Integer.parseInt(""+a+b); } }
class Solution { public: /** * 解码 * @param nums string字符串 数字串 * @return int整型 */ int solve(string nums) { vector<int> dp(nums.size()+1); if(nums.empty() || nums == "0") return 0; dp[0] = 1; for(int i = 1; i <= nums.size(); i++) { dp[i] = nums[i-1] == '0' ? 0 : dp[i-1]; if((i > 1) && ((nums[i-2] == '1') || (nums[i-2] == '2' && nums[i-1] <= '6'))) { dp[i] += dp[i-2]; } } return dp[nums.size()]; } };
class Solution { public: /** * 解码 * @param nums string字符串 数字串 * @return int整型 */ int solve(string nums) { // write code here if (nums.empty() || nums == "0") return 0; int n = nums.size(); vector<int> dp(n + 1, 0); dp[0] = 1; for (int i = 1; i <= n; ++i) { dp[i] = (nums[i - 1] == '0') ? 0 :dp[i - 1]; if (i > 1 && (nums[i - 2] == '1' || (nums[i - 2] == '2' && nums[i - 1] <= '6'))) { dp[i] += dp[i - 2]; } } return dp.back(); } };
class Solution: def solve(self , nums: str) -> int: # write code here if not nums&nbs***bsp;nums== '0': return 0 a = b = 1 # a f(i-2) b f(i-1) for i in range(1,len(nums)): tmp = nums[i-1:i+1] if tmp == '00': # 如果有00连续则无法翻译 返回0 return 0 # 有0的如 10 20看成可翻译的一个数,而不是两个数的情况 # c = a + b if '11' <= tmp <= '26' and '0' not in tmp else b c = a + b if '11' <= tmp <= '26' and tmp != '20' else b a, b = b, c return b有条件的青蛙跳, 不仅是11 到 26 还要对0进行处理
public int solve (String nums) { if(nums.equals("")) return 0; int n=nums.length(); int[]dp=new int[n+1];//dp[i]表示长度为0时译码数 dp[0]=1; dp[1]=nums.charAt(0)=='0'?0:1;//一位数只要不是0就是一种译码 for(int i=2;i<=n;i++){ int preTwo=Integer.parseInt(nums.substring(i-2,i));//计算自己和前一位是否能组成译码,前i-2和(i-1,i)形成一种译码情况 if(preTwo>=10&&preTwo<=26){ dp[i]=dp[i-2]; } //检查这一位能否单独译码(这时候的情况是前i-1个和i形成译码) if(nums.charAt(i-1)!='0') dp[i]+=dp[i-1]; } return dp[n]; }
class Solution: def solve(self , nums: str) -> int: # write code here n = len(nums) dp = [0] * (n+1) dp[0] = 1 dp[1] = 1 if nums[0] != '0' else 0 print(dp) for i in range(2, n+1): if nums[i-1] != '0': dp[i] += dp[i-1] if '10'<= nums[i-2:i] <= '26': dp[i] += dp[i-2] return dp[n]
public int solve (String nums) { // write code here int n = nums.length(); int[] dp = new int[n + 1]; // 定义:以nums[i - 1]结尾的字符串的译码次数 dp[0] = 1; // 初始为1(对于dp[2]有用) dp[1] = nums.charAt(0) == '0' ? 0 : 1; for(int i = 2; i <= n; i++) { // 两种译码情况,要么当前数字单独译码,要么与前一位数字结合译码 // 情况1:单独译码(条件是当前数字不是0才行) if(nums.charAt(i - 1) != '0') { dp[i] += dp[i - 1]; } // 情况2:要么与前一位数字结合译码,条件是结合后的数字不超过26 if(nums.charAt(i - 2) == '1' || (nums.charAt(i - 2) == '2' && nums.charAt(i - 1) <= '6')) { dp[i] += dp[i - 2]; } } return dp[n]; }
/** * 解码 这题目本质和矩形覆盖和上楼梯都是一样的 一次编一个一次编两个 * dp[i] 表示前i个字符的编码方式 * 因为0不能被编码所以会有很多特殊情况 * 1.当遍历到0 但前一个字符 不是1或2 无法编译返回0 * 2.当遍历到0 但前一个字符是1 或 2 dp[i] = dp[i-2] * 3.遍历到的不是0 但和前一个组成的二位数范围不在可解码范围内 dp[i] = dp[i-1] * 4 其他 dp[i] = dp[i-1] + dp[i-2] * * @param nums string字符串 数字串 * @return int整型 */ public int solve (String nums) { int m = nums.length(); // 因为最后要返回dp[m] 前m个字符的编码方式 m可以看出字符个数 int[] dp = new int[m + 1]; dp[1] = 1; dp[0] = 1; for(int i = 2; i <= m; i++){ // 如果遇到一个0前面不是1或者不是2直接返回0无法编译 if(nums.charAt( i -1 ) == '0' && (nums.charAt(i - 2) != '1' && nums.charAt(i - 2) != '2' )) return 0; // 如果是0 前面一个为1 if(nums.charAt( i -1 ) == '0') dp[i] = dp[i - 2]; else { if((Integer.valueOf(nums.substring(i -2, i)) <= 26 && Integer.valueOf(nums.substring(i -2, i)) > 10)){ dp[i] = dp[i - 1] + dp[i - 2]; }else dp[i] = dp[i - 1]; } } return dp[m]; }
/** * 解码 * @param nums string字符串 数字串 * @return int整型 */ function solve(nums) { let dp = new Array(nums.length + 1); dp[0] = 1; for (let i = 1; i <= nums.length; i++) { dp[i] = nums[i - 1] == '0' ? 0 : dp[i - 1]; if ((i > 1) && ((nums[i - 2] == '1') || (nums[i - 2] == '2' && nums[i - 1] <= '6'))) { dp[i] += dp[i - 2]; } } return dp[nums.length]; } module.exports = { solve: solve };