512 - 解码方法

5.19

这个题目真的写的我好憔悴啊。

刚开始的思路很正确,从后向前遍历字符串,

/* 当在原有的字符串的基础上重新加入一个新的数字时
            首先要判断,加入这个数字后,新的字符串是不是合法
                不合法有两层含义 :
                    1,出现“00”、“30”,“90”等,直接返回0就可以了
                    2,数字 只是单纯不在区间【1,26】之内。
            当加入新的数字时,新的字符串的长度为n
               如果数字是合法的    res[n] = res[n-1] + res[n-2]
               如果数字是不合法的  res[n] = res[n-1]

*/

采用非递归的方式,表达式也是正确的,但是有一下几个细节在最初的时候并没有考虑到。

1.数据可能是不合法的,这样就没有对应的解码方式

     1.1 字符串以0 开头

     1.2 字符串中含有“00”、“30”等情况

2. 初始条件没有设置正确。

     2.1 当最后两个字母为“10”、“11”、“31”、“01”大概这几种情况,需要认真考虑

3. 表达式还是欠考虑。

    3.1 比如 加上一个字符后,字符串的变化情况为 "111" -> "0111",

     3.2 在上述情况下,又加入字符,字符的变化情况为“0111”->"10111"

     3.3 继续加入字符,字符串的变化情况为“10111”->"110111"

在这种情况下,就不可以单纯地采用   res_2 = res_1; res_1=res;进行状态的变化了,需要进行特殊处理。

大概就是这样。现在思路清晰了,但是代码是一点儿一点儿加上去的,写的很不好。但是懒得重新按照完整的逻辑再来一遍了。就这样吧。

被破题整的很崩溃。

public class Solution {
    /**
     * @param s a string,  encoded message
     * @return an integer, the number of ways decoding
     */
    public int numDecodings(String s) {
        // Write your code here
        int length = s.length();
        if(length == 0){
            return 0;
        }
        if(s.startsWith("0")){
            return 0;
        }
        if(length == 1){
            return 1;
        }
        int flag = length - 2;
        int res = 0;
        if(s.charAt(length -1) != '0'){
            res = 1;
        }
        // substring(i,j) 包括i,却不包括j
        String tmp = s.substring(flag,length);
        int isLegal = isLegal(tmp);
        int res_1 = res;// 存储 n - 1 的值
        int res_2 = 0;// 存储 n - 2 的值
        /* 当在原有的字符串的基础上重新加入一个新的数字时
            首先要判断,加入这个数字后,新的字符串是不是合法
                不合法有两层含义 : 
                    1,出现“00”、“30”,“90”等,直接返回0就可以了
                    2,数字 只是单纯不在区间【1,26】之内。
            当加入新的数字时,新的字符串的长度为n
               如果数字是合法的    res[n] = res[n-1] + res[n-2]
               如果数字是不合法的  res[n] = res[n-1]
        */
        if(isLegal == 0){
            return 0;
        }
        if(isLegal == 1){
            res_2 = res_1;
            res_1 = res;
            res = res_1 + 1;
        }
        else{
            res_2 = res_1;
            res_1 = res;
            res = res_1;
        }
        
        while(flag > 0){
            flag --;
            tmp = s.substring(flag,length);
            isLegal = isLegal(tmp);
            if(isLegal == 0){
                return 0;
            }
            if(tmp.startsWith("0")){
                res_1 = 0;
                res_2 = res;
                continue;
            }
            if(tmp.charAt(2) == '0'){
                res_2 = 0;
                res_1 = res;
                continue;
            }
            //System.out.println("tmp:" + tmp + ";flag:" + (length - flag));
            //System.out.println("前:res:" + res +"; res1:" + res_1 + "; res2:" + res_2);
            if(isLegal == 1){
                res_2 = res_1;
                res_1 = res;
                res = res_1 + res_2;
                //System.out.println("数据合法");
            }
            else{
                res_2 = res_1;
                res_1 = res;
                res = res_1;
            }
            //System.out.println("后:res:" + res +"; res1:" + res_1 + "; res2:" + res_2);
            
            
        }
        return res;
    }
    // 要考虑00,30,40 这种无解码方式的情况
    public int isLegal(String s){
        // 1 代表合法  -1 代表超过26的情况,0 代表出现了00,30,40这种情况,
        int length = s.length();
        if(length <= 1){
            return -1;
        }
        int x = s.charAt(0) - '0';
        int y = s.charAt(1) - '0';
        //System.out.println("X:" + x + ";Y:" + y);
        if( y == 0 && x >= 3){
            return 0;
        }
        if( y == 0 && x == 0){
            return 0;
        }
        if(x == 0){
            return -1;
        }
        if(10*x + y <= 26){
            return 1;
        }
        return -1;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值