13.10 Decode Ways

Link: https://oj.leetcode.com/problems/decode-ways/

My thought: 

e.g. s = "123", s.length = 3. We can choose to split at position i after char i [0, n-1]. So there are 2^(n-1) .

But I still need to validate whether the splitted numbers are between [1, 26]

Approach I: DP from left to right

Time: O(n), Space: O(n) 

Reference: http://moisellegyg.blogspot.com/2014/04/leetcode-decode-ways.html

  1. s has only one character. If the character is '0', then return 0. Otherwise, return 1.
  2. s has at least two characters. We maintain an array count[n+1] to record the number of ways to decode s. Let count[i] be the number of ways to decode s[0..i-1]. We initialize count[0] = 1 and count[1] = 1. 

  • If  s[i-1]!='0', which means we can decode s[i-1] to some letter, then count[i] = count[i-1]
  • If  s[i-1,i] represents an integer in the range of [10,26], which means we can decode s[i-1,i] to some letter, then count[i] += count[i-2].
  • s[n] is the number of ways to decode s.  

public class Solution {
    //DP: from left to right. <span style="font-family: Arial, Helvetica, sans-serif;">ways[i]表示s[0...i-1]的解码方法数目</span>
    public int numDecodings(String s) {
        if(s == null || s.length() == 0) return 0;
        int[] ways = new int[s.length()+1];
        ways[0] = 1;//why>
        if(s.charAt(0) != '0'){
            ways[1] = 1;
        }
        for(int i = 2; i <= s.length(); i++){
            if(s.charAt(i-1) != '0'){
                ways[i] = ways[i-1];
            }
            else{
                ways[i] = 0;
            }
            if(s.charAt(i-2) == '1' || (s.charAt(i-2) == '2' && s.charAt(i-1) <= '6')) {
                ways[i] += ways[i-2]; 
            }
            
        }
        return ways[s.length()];
    }
}

http://blog.csdn.net/linhuanmars/article/details/24570759

has an Space = O(1) solution

Approach II: DP from right to left

public class Solution {
    //I don't understand what's the benefit of doing from right to left
    public int numDecodings(String s) {
        if(s == null || s.length() == 0) return 0;
        int[] ways = new int[s.length()+2];
        for(int i = 0; i < ways.length; i++){
            ways[i] = 1;
        }
        for(int i = s.length()-1; i>=0; i--){
            if(s.charAt(i) == '0'){
                ways[i] = 0;
            }
            else{
                ways[i] = ways[i+1];
            }
            if( i + 1 < s.length() && ((s.charAt(i) == '1' || (s.charAt(i) == '2' && s.charAt(i+1) <= '6')))) {
                ways[i] += ways[i+2]; 
            }
            
        }
        return ways[0];
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值