91. Decode Ways

Văn bản bài toán được dịch từ tiếng Nga theo ngôn ngữ giao diện. Mã không thay đổi.

Сообщение, содержащее буквы от A до Z, можно закодировать в числа с использованием следующего соответствия:

- 'A' -> "1"

- 'B' -> "2"

- ...

- 'Z' -> "26"

Для декодирования закодированного сообщения все цифры должны быть сгруппированы и затем отображены обратно в буквы с использованием обратного соответствия (существует несколько способов). НаVí dụ, "11106" можно представить как:

- "AAJF" с группировкой (1 1 10 6)

- "KJF" с группировкой (11 10 6)

Обратите внимание, что группировка (1 11 06) недопустима, потому что "06" не может быть преобразовано в 'F', так как "6" отличается от "06".

Для данной строки s, содержащей только цифры, return количество способов декодирования.

Тестовые случаи сформированы таким образом, что ответ укладывается в 32-битное số nguyên.

Ví dụ:

Input: s = "12"

Output: 2

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

C# lời giải

đã khớp/gốc
public class Solution {
    private Dictionary<int, int> memo = new Dictionary<int, int>();
    private int RecursiveWithMemo(int index, string s) {
        if (memo.ContainsKey(index)) {
            return memo[index];
        }
        if (index == s.Length) {
            return 1;
        }
        if (s[index] == '0') {
            return 0;
        }
        if (index == s.Length - 1) {
            return 1;
        }
        int ans = RecursiveWithMemo(index + 1, s);
        if (int.Parse(s.Substring(index, 2)) <= 26) {
            ans += RecursiveWithMemo(index + 2, s);
        }
        memo[index] = ans;
        return ans;
    }
    public int NumDecodings(string s) {
        return RecursiveWithMemo(0, s);
    }
}

C++ lời giải

bản nháp tự động, xem lại trước khi gửi
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    private unordered_map<int, int> memo = new unordered_map<int, int>();
    private int RecursiveWithMemo(int index, string s) {
        if (memo.count(index)) {
            return memo[index];
        }
        if (index == s.size()) {
            return 1;
        }
        if (s[index] == '0') {
            return 0;
        }
        if (index == s.size() - 1) {
            return 1;
        }
        int ans = RecursiveWithMemo(index + 1, s);
        if (int.Parse(s.Substring(index, 2)) <= 26) {
            ans += RecursiveWithMemo(index + 2, s);
        }
        memo[index] = ans;
        return ans;
    }
    public int NumDecodings(string s) {
        return RecursiveWithMemo(0, s);
    }
}

Java lời giải

đã khớp/gốc
class Solution {
    Map<Integer, Integer> memo = new HashMap<>();

    public int numDecodings(String s) {
        return recursiveWithMemo(0, s);
    }

    private int recursiveWithMemo(int index, String str) {
        if (memo.containsKey(index)) {
            return memo.get(index);
        }

        if (index == str.length()) {
            return 1;
        }

        if (str.charAt(index) == '0') {
            return 0;
        }

        if (index == str.length() - 1) {
            return 1;
        }

        int ans = recursiveWithMemo(index + 1, str);
        if (Integer.parseInt(str.substring(index, index + 2)) <= 26) {
            ans += recursiveWithMemo(index + 2, str);
        }

        memo.put(index, ans);

        return ans;
    }
}

JavaScript lời giải

đã khớp/gốc
var numDecodings = function (s) {
    let memo = new Object();
    return recursiveWithMemo(0, s, memo);
};
const recursiveWithMemo = (index, str, memo) => {
    if (memo.hasOwnProperty(index)) {
        return memo[index];
    }
    if (index == str.length) {
        return 1;
    }
    if (str.charAt(index) == "0") {
        return 0;
    }
    if (index == str.length - 1) {
        return 1;
    }
    let ans = recursiveWithMemo(index + 1, str, memo);
    if (parseInt(str.substring(index, index + 2)) <= 26) {
        ans += recursiveWithMemo(index + 2, str, memo);
    }
    memo[index] = ans;
    return ans;
};

Python lời giải

đã khớp/gốc
from functools import lru_cache

class Solution:

    @lru_cache(maxsize=None)
    def recursiveWithMemo(self, index, s) -> int:
        if index == len(s):
            return 1

        if s[index] == "0":
            return 0

        if index == len(s) - 1:
            return 1

        answer = self.recursiveWithMemo(index + 1, s)
        if int(s[index: index + 2]) <= 26:
            answer += self.recursiveWithMemo(index + 2, s)

        return answer

    def numDecodings(self, s: str) -> int:
        return self.recursiveWithMemo(0, s)

Go lời giải

đã khớp/gốc
func recursiveWithMemo(index int, str string, memo
map[int]int) int {
    if val, ok := memo[index]; ok {
        return val
    }
    if index == len(str) {
        return 1
    }
    if str[index] == '0' {
        return 0
    }
    if index == len(str)-1 {
        return 1
    }
    ans := recursiveWithMemo(index+1, str, memo)
    substrNum, _ := strconv.Atoi(str[index : index+2])
    if substrNum <= 26 {
        ans += recursiveWithMemo(index+2, str, memo)
    }
    memo[index] = ans
    return ans
}

func numDecodings(s string) int {
    memo := make(map[int]int)
    return recursiveWithMemo(0, s, memo)
}

Algorithm

1️⃣

Đầu vàoим в рекурсию с данной строкой, начиная с индекса 0.

2️⃣

Для окончательного случая рекурсии мы проверяем конец строки. Если мы достигли конца строки, возвращаем 1. Каждый раз, когда мы Đầu vàoим в рекурсию, это для подстроки исходной строки. Если первый символ в подстроке равен 0, то прекращаем этот путь, возвращая 0. Таким образом, этот путь не будет влиять на количество способов.

3️⃣

Мемоизация помогает снизить Complexity, которая иначе была бы экспоненциальной. Мы проверяем словарь memo, чтобы увидеть, существует ли уже результат для данной подстроки. Если результат уже находится в memo, мы возвращаем этот результат. В противном случае количество способов для данной строки определяется путем рекурсивного вызова функции с индексом +1 для следующей подстроки и индексом +2 после проверки на валидность двузначного декодирования. Результат также сохраняется в memo с ключом как текущий индекс, чтобы сохранить его для будущих пересекающихся подзадач.

😎

Vacancies for this task

việc làm đang hoạt động with overlapping task tags are đã hiển thị.

Tất cả việc làm
Chưa có việc làm đang hoạt động.