LeetCode [91] 解码方法

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) 。

题目分析

就以例子中的226来看。首先判断2是否为0以及是否为小于26,如果满足条件那么方法数+1,接着看22,也满足加1,接着看第二个2,发现满足加1。从这个可以看出来只要开始遍历,分别看单数字和与后面一个数字的组合,判断是否满足条件即可,满足就加1不满足就下一个。那么这样就可以用递归做了。

源码

class Solution {
private int count = 0;
public int numDecodings(String s) {
    if(s.length() == 0) return 0;
    char[] cs = s.toCharArray();
    int[] a = new int[cs.length];
    for(int i = 0;i < cs.length;i++){
        a[i] = cs[i] - '0';
    }
    //先将字符串转换成整数类型的数组
    dfs(a,0,a[0]);
    return count;
}
public void dfs(int[] a,int idx,int num){
    if(num == 0 || num > 26) return;
     // num不能为0,不能大于26
    // 到达末尾,判断num是否合法
    if(idx == a.length - 1) {
        if(num <= 26) count++;
        return;
    }
    dfs(a,idx + 1,a[idx + 1]); 
    // 单个数字为一组    
    dfs(a,idx + 1,num * 10 + a[idx + 1]); 
    // 和后一个数字为一组
}
}

改进

事实证明,当我提交的时候时间600ms的我惊呆了,竟然这么慢,不过确实两次递归不慢才怪了相当于遍历了两遍数组,时间的复杂度就上升到了O(m^2)。那就应该换一种方法来降低复杂度,从上面的推理可能还看不出什么,那么下面就用更长一点的字符串来展示一下。以2331231216为例吧,这个肯定够长了。
从0开始,0为索引值。
2成立+1,23成立+1;
3成立+1,33不成立保持+1;
3成立+1,31不成立保持+1;
1成立+1,12成立+1……
可以看出来count是怎么加的呢?
如果dp[n-1]满足条件就为1,10*dp[n-2]+dp[n-1]满足条件就再加1
可以从我的表达式看出来,这就是用动态规划了。
为什么用n-1 呢,因为前两个为初始状态,所以要从第2个开始,这样就能保持空间复杂度为O(1)了

改进代码

class Solution {
public int numDecodings(String s) {
    int n = s.length();
    int[] dp = new int[n+1];
    //dp数组用来保存是否满足条件
    if(s.charAt(0)!='0') 
       dp[1] = dp[0] = 1;
    for(int i = 2;i<=n;i++){
        if(s.charAt(i-1)=='0'){
            if(s.charAt(i-2)=='1' || s.charAt(i-2)=='2') 
                dp[i] = dp[i-2];
            else
                return 0;
        }
        else{
            dp[i] = dp[i-1];
            if(s.charAt(i-2)!='0'){
                int t = 10*(s.charAt(i-2)-'0')+s.charAt(i-1)-'0';
                if(t<=26)
                    dp[i] += dp[i-2];
            }
        }
    }
    return dp[n];
}
}

分析

第一个时间复杂度为O(m^2)
第二个就是O(n)
空间复杂度都为O(1)

[1]https://leetcode-cn.com/problems/decode-ways/submissions/

你可能感兴趣的:(刷题刷刷刷)