Easy
题目描述
给你字符串 key 和 message ,分别表示一个加密密钥和一段加密消息。解码 message 的步骤如下:
- 使用
key中 26 个英文小写字母第一次出现的顺序作为替换表的顺序。 - 将替换表与普通英文字母表对齐。
- 按照替换表替换
message中的每个字母。 - 空格
' '应当保持不变。
例如,给出 key = "happy boy"(实际的密钥应该包含字母表中的每个字母至少一次),我们得到部分替换表:'h' -> 'a', 'a' -> 'b', 'p' -> 'c', 'y' -> 'd', 'b' -> 'e', 'o' -> 'f'。
返回解码后的消息。
示例 1:
输入:key = "the quick brown fox jumps over the lazy dog", message = "vkbs bs t suepuv"
输出:"this is a secret"
解释:上图显示了替换表。
它是通过取 "the quick brown fox jumps over the lazy dog" 中每个字母的第一次出现来获得的。
示例 2:
输入:key = "eljuxhpwnyrdgtqkviszcfmabo", message = "zwx hnfx lqantp mnoeius ycgk vcnjrdb"
输出:"the five boxing wizards jump quickly"
解释:上图显示了替换表。
它是通过取 "eljuxhpwnyrdgtqkviszcfmabo" 中每个字母的第一次出现来获得的。
提示:
26 <= key.length <= 2000key由小写英文字母和' '组成key包含英文字母表中每个字母('a'到'z')至少一次1 <= message.length <= 2000message由小写英文字母和' '组成
解题思路
解题思路
这道题的核心是构建一个字符映射表,将密钥中的字符映射到标准字母表。
算法步骤:
- 构建映射表:遍历密钥字符串,记录每个字母第一次出现的位置,按顺序映射到 ‘a’ 到 ‘z’
- 解码消息:使用构建的映射表对消息进行字符替换
具体实现:
- 使用哈希表记录密钥字符到标准字母的映射关系
- 遍历密钥时,只记录每个字符的第一次出现,忽略空格和重复字符
- 使用一个计数器来追踪当前应该映射到的标准字母(从 ‘a’ 开始)
- 最后遍历消息字符串,根据映射表进行字符替换,空格保持不变
时间复杂度: O(n + m),其中 n 是密钥长度,m 是消息长度 空间复杂度: O(1),映射表最多存储 26 个字符映射
代码实现
class Solution {
public:
string decodeMessage(string key, string message) {
unordered_map<char, char> mapping;
char current = 'a';
// 构建映射表
for (char c : key) {
if (c != ' ' && mapping.find(c) == mapping.end()) {
mapping[c] = current++;
}
}
// 解码消息
string result;
for (char c : message) {
if (c == ' ') {
result += ' ';
} else {
result += mapping[c];
}
}
return result;
}
};
class Solution:
def decodeMessage(self, key: str, message: str) -> str:
mapping = {}
current = ord('a')
# 构建映射表
for c in key:
if c != ' ' and c not in mapping:
mapping[c] = chr(current)
current += 1
# 解码消息
result = []
for c in message:
if c == ' ':
result.append(' ')
else:
result.append(mapping[c])
return ''.join(result)
public class Solution {
public string DecodeMessage(string key, string message) {
Dictionary<char, char> mapping = new Dictionary<char, char>();
char current = 'a';
// 构建映射表
foreach (char c in key) {
if (c != ' ' && !mapping.ContainsKey(c)) {
mapping[c] = current++;
}
}
// 解码消息
StringBuilder result = new StringBuilder();
foreach (char c in message) {
if (c == ' ') {
result.Append(' ');
} else {
result.Append(mapping[c]);
}
}
return result.ToString();
}
}
/**
* @param {string} key
* @param {string} message
* @return {string}
*/
var decodeMessage = function(key, message) {
const map = new Map();
let alphabet = 'abcdefghijklmnopqrstuvwxyz';
let alphabetIndex = 0;
for (let char of key) {
if (char !== ' ' && !map.has(char)) {
map.set(char, alphabet[alphabetIndex]);
alphabetIndex++;
}
}
let result = '';
for (let char of message) {
if (char === ' ') {
result += ' ';
} else {
result += map.get(char);
}
}
return result;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n + m) | n 为 key 长度,m 为 message 长度,需要遍历两个字符串各一次 |
| 空间复杂度 | O(1) | 映射表最多存储 26 个字符映射,为常数空间 |