O(n) | O(1)
We use tabulation dp to store the number of possible messages for i characters.\n\nFor i + 1-th character, the number of messages is dp[i + 1] = dp[i], plus:\n-
We use tabulation `dp` to store the number of possible messages for `i` characters.\n\nFor `i + 1`-th character, the number of messages is `dp[i + 1] = dp[i]`, plus:\n- `dp[i - 1]` if `key[i + 1] == key[i]`\n- `dp[i - 2]` if `key[i + 1] == key[i - 1]`\n- `dp[i - 3]` if `key[i + 1] == key[i - 2]`\n- `dp[i - 4]` if `key[i + 1] == key[i - 3]` and `key[i + 1]` is either 7 or 9.\n\nNote that we only need to store the tabulation for 4 previous positions. We can use a circular array to achieve O(1) memory complexity.\n\n**C++**\n```cpp\nint countTexts(string k) {\n    int dp[5] = {1, 1, 1, 1, 1}, n = k.size();\n    for (int i = n - 1; i >= 0; --i) {\n        dp[i % 5] = 0;\n        int max_j = min(n, i + (k[i] == \'7\' || k[i] == \'9\' ? 4 : 3));\n        for (int j = i; j < max_j && k[i] == k[j]; ++j)\n            dp[i % 5] = (dp[i % 5] + dp[(j + 1) % 5]) % 1000000007;\n    }\n    return dp[0];\n} \n```
[]