Given a string s
representing a mapping from integers to lowercase English letters, your task is to decrypt it into the original string. The mapping is defined as follows:
'a'
to 'i'
are represented by '1'
to '9'
.'j'
to 'z'
are represented by '10#'
to '26#'
.
The string s
consists of digits and the '#'
character. Each mapping is non-overlapping and there is exactly one way to decode s
.
Example:
Input: s = "10#11#12"
Output: "jkab"
Constraints:
1 <= s.length <= 1000
s
contains only digits and '#'
characterss
At first glance, this problem looks like a string parsing task. The key challenge is to recognize two types of encodings: single digits ('1'
to '9'
) and two digits followed by '#'
('10#'
to '26#'
).
A brute-force approach would be to check every possible substring, but since there is only one valid way to decode the string, we can process it from left to right (or right to left) and look for '#'
characters to identify two-digit mappings.
We realize that whenever we see a '#'
, the two digits before it represent a letter from 'j'
to 'z'
. Otherwise, each digit stands alone as a letter from 'a'
to 'i'
.
By shifting from checking all possibilities to simply looking for '#'
and processing accordingly, we can make the solution much more efficient and straightforward.
Here's how we can systematically solve the problem:
'#'
), parse the two digits, convert them to a letter, and move the pointer ahead by 3.
'a'
is at position 1, so chr(int(num) + ord('a') - 1)
gives the correct character.
This approach is efficient and clear, using simple string manipulation and character arithmetic.
Let's walk through the example s = "10#11#12"
step by step:
'#'
, so s[0:2]
is "10"
. Convert 10
to 'j'
. Move to index 3.
'#'
. s[3:5]
is "11"
. Convert 11
to 'k'
. Move to index 6.
'#'
ahead, so process s[6]
which is '1'
. Convert 1
to 'a'
. Move to index 7.
'2'
. Convert 2
to 'b'
. Move to index 8 (end).
The result is "jkab"
.
Brute-force Approach: If we tried every possible substring split, time complexity would be exponential (O(2^n)), but the problem guarantees one valid decoding.
Optimized Approach: Our solution processes each character at most once, so
s
.
To solve the "Decrypt String from Alphabet to Integer Mapping" problem, we leverage the unique mapping pattern and the guarantee of a single valid solution. By scanning for '#'
characters and decoding accordingly, we create a simple, efficient algorithm. The key insight is recognizing the two types of encodings and using straightforward string and character operations to decrypt the message.
class Solution:
def freqAlphabets(self, s: str) -> str:
res = []
i = 0
while i < len(s):
if i + 2 < len(s) and s[i + 2] == '#':
num = int(s[i:i+2])
res.append(chr(num + ord('a') - 1))
i += 3
else:
num = int(s[i])
res.append(chr(num + ord('a') - 1))
i += 1
return ''.join(res)
class Solution {
public:
string freqAlphabets(string s) {
string res = "";
int i = 0, n = s.size();
while (i < n) {
if (i + 2 < n && s[i + 2] == '#') {
int num = stoi(s.substr(i, 2));
res += (char)('a' + num - 1);
i += 3;
} else {
int num = s[i] - '0';
res += (char)('a' + num - 1);
i += 1;
}
}
return res;
}
};
class Solution {
public String freqAlphabets(String s) {
StringBuilder res = new StringBuilder();
int i = 0, n = s.length();
while (i < n) {
if (i + 2 < n && s.charAt(i + 2) == '#') {
int num = Integer.parseInt(s.substring(i, i + 2));
res.append((char)('a' + num - 1));
i += 3;
} else {
int num = s.charAt(i) - '0';
res.append((char)('a' + num - 1));
i += 1;
}
}
return res.toString();
}
}
var freqAlphabets = function(s) {
let res = "";
let i = 0;
while (i < s.length) {
if (i + 2 < s.length && s[i + 2] === '#') {
let num = parseInt(s.substring(i, i + 2), 10);
res += String.fromCharCode(96 + num);
i += 3;
} else {
let num = parseInt(s[i], 10);
res += String.fromCharCode(96 + num);
i += 1;
}
}
return res;
};