A daily Rust-LeetCode (2019-06-08)

A daily Rust-LeetCode (2019-06-08) 91. decoding method

Adhere to a question every day, brush title learning Rust.

Title Description

https://leetcode-cn.com/problems/decode-ways/

Message that includes the letters AZ is encoded by:

'A' ->. 1
'B' -> 2
...
'the Z' -> 26 is
determined to contain only non-empty string of numbers, calculate the total number of the decoding method.

Example 1:

Input: "12"
Output: 2
explanation: It may be decoded as "AB" (1 2) or "L" (12).
Example 2:

Input: "226"
Output: 3
explain: it can be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6) .

Problem-solving process

Thinking:
Because according to the numbering, only two consecutive and efficient encoding is not more than 26,
of length N decoding method:
A [0 ... N-. 1] = {A [0 ... N-2 ] + a [N-1] } + {a [0 ... N-3] + a [n-2, n-1]}
range If the latter a [n-2, n- 1] in the within the 26 words
is somewhat similar to Fibonacci number solving process

struct Solution {}
impl Solution {
    pub fn num_decodings(s: String) -> i32 {
        Solution::decodings(&s.as_bytes().iter().map(|i| i - ('0' as u8)).collect())
    }
    fn decodings(v: &Vec<u8>) -> i32 {
        if v.len() <= 0 {
            return 0;
        }
        let mut vcnt = Vec::with_capacity(v.len());
        if v[0] == 0 {
            return 0;
        }
        vcnt.push(1); //只有一个字符的时候肯定是只有一种编码
        for i in 1..v.len() {
            let mut cnt = 0;
            if v[i] != 0 {
                //只要不是0的数字,都是有效的编码
                cnt = vcnt[i - 1]; //第一种分法
            }
            if i >= 1 {
                //考虑 i-1,i联合起来的情形
                let n = v[i - 1] * 10 + v[i];
                if (v[i - 1] == 1 || v[i - 1] == 2) && n <= 26 {
                    //有效编码
                    if i >= 2 {
                        cnt += vcnt[i - 2];
                    } else {
                        cnt += 1; //考虑到只有两个字符,这时候下标就出界了.
                    }
                } else if n == 0 {
                    return 0; //连续的两个数字0,是不可能被编码的,后续的也无效了
                } else {
                    //超过的,不能有效编码,但是输入是合法的.
                }
            }
            vcnt.push(cnt);
        }
        vcnt[v.len() - 1]
    }
}
#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn test_decodings() {
        assert_eq!(2, Solution::num_decodings(String::from("12")));
        assert_eq!(0, Solution::num_decodings(String::from("")));
        assert_eq!(0, Solution::num_decodings(String::from("0")));
        assert_eq!(1, Solution::num_decodings(String::from("10")));
        assert_eq!(1, Solution::num_decodings(String::from("101")));
        assert_eq!(0, Solution::num_decodings(String::from("100")));
        assert_eq!(1, Solution::num_decodings(String::from("1")));
        assert_eq!(3, Solution::num_decodings(String::from("226")));
        assert_eq!(2, Solution::num_decodings(String::from("227")));
    }
}

A little sentiment

This topic is very simple, but it was the pit several times in dealing with zero,
it did not pay attention to this case 0
but later considered relatively simple, it wrong a few times.
There are the following situations:

  1. Illegal input
    leading zeros, continuous 00 are unable to effectively decode
  2. 0 appears in the middle of
    10 is lawful, unlawful 30, 101 note does not satisfy the second split case, because 01 is not a valid encoding

    other

Welcome attention to my GitHub , this project can be found all code article.

Guess you like

Origin www.cnblogs.com/baizx/p/10989966.html