Giả sử có một tin nhắn chứa các chữ cái từ A-Z đang được mã hóa thành các số bằng cách ánh xạ sau -
'A' -> 1, 'B' -> 2, ..., 'Z' -> 26
Bây giờ, chuỗi được mã hóa cũng có thể chứa ký tự '*', có thể được coi là một trong các số từ 1 đến 9. Vì vậy, nếu chúng ta có thông báo được mã hóa chứa các chữ số và ký tự '*', thì chúng ta phải tìm tổng số cách giải mã nó. Nếu câu trả lời rất dài, chúng ta có thể sử dụng mod 109 + 7 để có kết quả cuối cùng. Vì vậy, nếu đầu vào chỉ là *, thì có thể có 9 cách khả thi, đây đều là các số từ 1 đến 9, vì vậy đây là A đến I.
Để giải quyết vấn đề này, chúng tôi sẽ làm theo các bước sau -
- Xác định một hàm add (), hàm này sẽ nhận a, b,
- return ((a mod m) + (b mod m)) mod m
- Xác định một hàm mul (), điều này sẽ nhận a, b,
- return ((a mod m) * (b mod m)) mod m
- Từ phương thức chính, hãy làm như sau -
- n:=kích thước của s
- Xác định một mảng dp có kích thước n + 1
- dp [0]:=1
- nếu s [0] giống với '0', thì -
- trả về 0
- dp [1]:=9 khi s [0] giống với '*' nếu không thì 1
- để khởi tạo i:=2, khi i <=n, cập nhật (tăng i lên 1), thực hiện -
- thứ nhất:=s [i - 2], thứ hai:=s [i - 1]
- nếu thứ hai giống với '*', thì -
- dp [i]:=add (dp [i], mul (9, dp [i - 1]))
- ngược lại khi giây> '0', thì -
- dp [i]:=dp [i - 1]
- nếu đầu tiên giống với '*', thì -
- nếu thứ hai giống với '*', thì -
- dp [i]:=add (dp [i], mul (15, dp [i - 2]))
- ngược lại khi thứ hai <='6', thì -
- dp [i]:=add (dp [i], mul (2, dp [i - 2]))
- Mặt khác
- dp [i]:=add (dp [i], mul (1, dp [i - 2]))
- nếu thứ hai giống với '*', thì -
- nếu không khi đầu tiên giống với '1' hoặc đầu tiên giống với '2', thì -
- nếu thứ hai giống với '*', thì -
- nếu đầu tiên giống với '1', thì -
- dp [i]:=add (dp [i], mul (9, dp [i - 2]))
- nếu không, khi đầu tiên giống với '2', sau đó -
- dp [i]:=add (dp [i], mul (6, dp [i - 2]))
- nếu đầu tiên giống với '1', thì -
- ngược lại khi (đầu tiên - '0') * 10 + (thứ hai - '0') <=26, thì -
- dp [i]:=add (dp [i], dp [i - 2])
- nếu thứ hai giống với '*', thì -
- trả về dp [n]
Hãy cùng chúng tôi xem cách triển khai sau để hiểu rõ hơn -
Ví dụ
#include <bits/stdc++.h> using namespace std; typedef long long int lli; const lli m = 1e9 + 7; class Solution { public: lli add(lli a, lli b){ return ((a % m) + (b % m)) % m; } lli mul(lli a, lli b){ return ((a % m) * (b % m)) % m; } int numDecodings(string s) { int n = s.size(); vector <int> dp(n + 1); dp[0] = 1; if(s[0] == '0') return 0; dp[1] = s[0] == '*' ? 9 : 1; for(int i = 2; i <= n; i++){ char first = s[i - 2]; char second = s[i - 1]; if(second == '*'){ dp[i] = add(dp[i], mul(9, dp[i - 1])); }else if(second > '0'){ dp[i] = dp[i - 1]; } if(first == '*'){ if(second == '*'){ dp[i] = add(dp[i], mul(15, dp[i - 2])); }else if (second <= '6'){ dp[i] = add(dp[i], mul(2, dp[i - 2])); }else{ dp[i] = add(dp[i], mul(1, dp[i - 2])); } }else if(first == '1' || first == '2'){ if(second == '*'){ if(first == '1'){ dp[i] = add(dp[i], mul(9, dp[i - 2])); }else if(first == '2'){ dp[i] = add(dp[i], mul(6, dp[i - 2])); } }else if((first - '0') * 10 + (second - '0') <= 26){ dp[i] = add(dp[i], dp[i - 2]); } } } return dp[n]; } }; main(){ Solution ob; cout << (ob.numDecodings("2*")); }
Đầu vào
“2*”
Đầu ra
15