Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- /*
- QUESTION - https://www.youtube.com/watch?v=jFZmBQ569So&list=PL-Jc9J83PIiG8fE6rj9F5a6uyQ5WPdqKy&index=20 (Count the number of Encodings)
- */
- void getEncodings(string digits, string path, vector < char > & encodings) {
- //base case
- //string is empty, which means we have processed all digits
- if (digits.empty()) {
- cout << path << '\n';
- return;
- }
- //invalid case
- //If the first char is '0', the prefixes formed by it will be invalid, i.e. '0' & "0i"
- //eg "04356" => prefixes formed => oneChar = '0' & twoChar = "04" which are both invalid, so we can directly return
- if (digits[0] == '0') {
- return;
- }
- // levels - digits (the whole string)
- // options - the starting 2 prefixes of digits
- // one digit at a time
- int oneChar = stoi(digits.substr(0, 1));
- getEncodings(digits.substr(1), path + encodings[oneChar], encodings);
- //two digits at a time
- //we can only get a substring of 2 length if the string is atleast of length = 2
- if (digits.size() >= 2) {
- int twoChar = stoi(digits.substr(0, 2));
- //We can only have this call if twoChar corresponds to a valid encoding
- // substring of length 2, which is: 10 <= twoChar <= 26
- if (twoChar >= 10 && twoChar <= 26) {
- getEncodings(digits.substr(2), path + encodings[twoChar], encodings);
- }
- }
- }
- int getEncodingsMemo(string digits, vector < char > & encodings, unordered_map < string, int > & memo) {
- /*
- The only thing changing here is digits
- So we should be able to memoise the code with a single key = digits.
- Definition = memo(digits) = Number of encodings possible when string = digits.
- */
- if (digits.empty()) {
- return 1;
- }
- if (digits[0] == '0') {
- return 0;
- }
- //memo Check
- if (memo.count(digits) > 0) {
- return memo[digits];
- }
- int totalEncodingsOneChar = 0, totalEncodingsTwoChar = 0;
- //one digit at a time
- int oneChar = stoi(digits.substr(0, 1));
- totalEncodingsOneChar = getEncodingsMemo(digits.substr(1), encodings, memo);
- //two digits at a time
- if (digits.size() >= 2) {
- int twoChar = stoi(digits.substr(0, 2));
- // substring of length 2, which is: 10 <= twoChar <= 26
- if (twoChar >= 10 && twoChar <= 26) {
- totalEncodingsTwoChar = getEncodingsMemo(digits.substr(2), encodings, memo);
- }
- }
- return memo[digits] = totalEncodingsOneChar + totalEncodingsTwoChar;
- }
- int getEncodingsDP(string & digits) {
- /*
- Storage & Meaning - dp[i] = Number of encodings possible for strings starting at index i (upto n - 1).
- */
- int n = digits.size();
- vector<int> dp(n, 0);
- /*
- Direction - Smallest Problem at: dp[n - 1](string starting at index [n - 1] and ending at [n - 1])
- Largest Problem at: dp[0] (String starting at index 0, original string)
- */
- //edge case
- dp[n - 1] = digits[n - 1] == '0' ? 0 : 1;
- /*
- Travel & Solve - Travel from smallest to largest problem to get the answer to original problem
- */
- for(int i = n - 2; i >= 0; i--){
- if(digits[i] != '0'){
- dp[i] += dp[i + 1];
- if(i <= n - 2){
- int twoCharInt = stoi(digits.substr(i, 2));
- if(twoCharInt >= 10 && twoCharInt <= 26){
- dp[i] += i == n - 2 ? 1 : dp[i + 2];
- }
- }
- }
- }
- return dp[0];
- }
- int main() {
- // your code goes here
- string digits;
- cin >> digits;
- vector < char > encodings(27, -1);
- for (int i = 1; i <= 26; i++) {
- encodings[i] = (char)(i - 1 + 'a');
- }
- //Recursive Call with print
- //getEncodings(digits, "", encodings);
- //Memo Call
- // unordered_map < string, int > memo;
- // cout << getEncodingsMemo(digits, encodings, memo) << '\n';
- // cout << stoi("03") << '\n';
- //DP Call
- cout << getEncodingsDP(digits) << '\n';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement