LeetCode每日一题(Decode Ways)

给定一个只包含从'A'到'Z'的字母映射到1-26数字的编码规则,解码一个只包含数字的字符串。返回解码方法的数量,注意不允许存在前导零导致错误的解码。例如,输入"12"可能解码为"AB"或"L",输入"226"可能解码为"BZ","VF"或"BBF"。当输入包含"0"时,如果没有对应以0开头的字母,则解码方法为0。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A message containing letters from A-Z can be encoded into numbers using the following mapping:

‘A’ -> “1”
‘B’ -> “2”

‘Z’ -> “26”
To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, “11106” can be mapped into:

“AAJF” with the grouping (1 1 10 6)
“KJF” with the grouping (11 10 6)
Note that the grouping (1 11 06) is invalid because “06” cannot be mapped into ‘F’ since “6” is different from “06”.

Given a string s containing only digits, return the number of ways to decode it.

The answer is guaranteed to fit in a 32-bit integer.

Example 1:

Input: s = “12”
Output: 2

Explanation:
“12” could be decoded as “AB” (1 2) or “L” (12).

Example 2:

Input: s = “226”
Output: 3

Explanation:

“226” could be decoded as “BZ” (2 26), “VF” (22 6), or “BBF” (2 2 6).

Example 3:

Input: s = “0”
Output: 0

Explanation:

There is no character that is mapped to a number starting with 0. The only valid mappings with 0 are ‘J’ -> “10” and ‘T’ -> “20”, neither of which start with 0.
Hence, there are no valid ways to decode this since all digits need to be mapped.

Example 4:

Input: s = “06”
Output: 0

Explanation:

“06” cannot be mapped to “F” because of the leading zero (“6” is different from “06”).

Constraints:

  • 1 <= s.length <= 100
  • s contains only digits and may contain leading zero(s).

这题最好的讲解就是代码, 不过我不保证我的代码是最优雅的,应该有不少地方还可以简化,但是整体的思路应该没问题


代码实现(Rust):

impl Solution {
    pub fn num_decodings(s: String) -> i32 {
        // 如果只有一个字符则判断是不是'0'
        if s.len() == 1 {
            if s == "0" {
                return 0;
            }
            return 1;
        }
        let chars: Vec<char> = s.chars().collect();
        let length = chars.len();
        let mut dp = vec![0; s.len()];
        // 如果最后一个字符是'0', 则当前解法为0, 如果是其他字符则当前解法为1
        if chars[length-1] != '0' {
            dp[length-1] = 1
        } 
        // 判断倒数第二个字符的情况
        match chars[chars.len()-2] {
            // 为'0'的话, 则当前解法为0
            '0' => dp[length-2] = 0,
            // 为'1'的情况
            '1' => {
                // 如果最后一个字符为'0', 则当前解法为1, 因为'10'只有一种解法
                if chars[length-1] == '0' {
                    dp[length-2] = 1;
                } else {
                    // 其他字符的话, 则当前解法为2, e.g '12' => [ ['1', '2'], ['12'] ]
                    dp[length-2] = 2; 
                }
            },
            // 为'2'的情况
            '2' => {
                // 判断最后一个字符
                match chars[length-1] {
                    // e.g '28' => [ ['2', '8'] ]
                    '0' | '7' | '8' | '9' => dp[length-2] = 1,
                    // e.g '21' => [ ['2', '1'], ['21'] ]
                    _ => dp[length-2] = 2,
                }
            },
            // '3', '4'...'8', '9'
            _ =>  {
                // e.g '40' => invalid
                if chars[length-1] == '0' {
                    return 0;
                } else {
                    // e.g '36' => [ ['3', '6' ] ]
                    dp[length-2] = 1;
                }

            }
        }
        for i in (0..length-2).rev() {
            match chars[i] {
                '0' => dp[i] = 0,
                '1' => {
                    if chars[i+1] == '0' {
                        // e.g '10...' => [ ['10', ...] ]
                        dp[i] = dp[i+2];
                    } else {
                        // e.g '11...' => [ ['1', '1...'], ['11', ...] ]
                        dp[i] = dp[i+1] + dp[i+2];
                    }
                },
                '2' => {
                    match chars[i+1] {
                        // e.g '20...' => [ ['20', ...] ]
                        '0' => dp[i] = dp[i+2],
                        // e.g '27...' => [ ['2', '7...'] ]
                         '7' | '8' | '9' => dp[i] = dp[i+1],
                         // e.g '23...' => [ ['2', '3...'], ['23', ...] ]
                        _ => dp[i] = dp[i+1] + dp[i+2],
                    }
                },
                _ =>  {
                    // e.g '50' => invalid
                    if chars[i+1] == '0' {
                        return 0;
                    } else {
                        // e.g '6...'  => [ ['6', ...] ]
                        dp[i] = dp[i+1];
                    }
                }
            }
        }
        dp[0]
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值