271. 字符串的编码与解码(中等)
题目
请设计两个函数:encode 把若干字符串合并成一个字符串;decode 再把这个字符串还原成原来的字符串列表。
难点在于:每个字符串可以是 256 个 ASCII 字符中的任意字符,包括 #、,、数字、空格,甚至空串。因此不能随便选一个“分隔符”直接拼接。
自造示例:["hello","wo#rld",""] 可编码为 "5#hello6#wo#rld0#",再解码必须得到原来的三个字符串。
约束:1 ≤ strs.length ≤ 200;0 ≤ strs[i].length ≤ 200;字符来自 256 个 ASCII 字符。
思路
一句话:把“找分隔符”换成“先写长度,再写内容”。
最直白的做法是选一个字符当分隔符,例如 ",",编码时 join、解码时 split。如果字符串里永远不会出现逗号,这没问题;但本题字符可以是任意 ASCII 字符,逗号、#、反斜杠都可能出现在内容里,解码时就无法判断它是分隔符还是内容。想用转义(遇到特殊字符就加 )虽然可行,但编码要扫描、解码要维护转义状态,边界多、容易错。
关键观察:与其让解码器“猜边界”,不如让编码串“自己告诉解码器边界”。在每个字符串前面放 长度#,解码时先读数字直到 #,得到长度,再按这个长度精确切出字符串。这样字符串内容里即使有 # 或数字,也绝不会被误认,因为解码器切完指定长度后,会直接跳到下一个长度字段。
这种“长度 + 分隔 + 内容”的格式自描述、无歧义,而且只需顺序扫描一遍,选它。
解法
两个方向都按同一套规则走:
- 编码:对每个
s,依次追加len(s)、#、s。 - 解码:指针
i从 0 开始;读出i到#之间的数字作为长度L;从#后一位开始切L个字符;指针跳到下一段。
| 指针 i | 读到字段 | 长度 | 切出的字符串 | 更新后 i |
|---|---|---|---|---|
| 0 | 5# | 5 | hello | 7 |
| 7 | 6# | 6 | wo#rld | 15 |
| 15 | 0# | 0 | “” | 17 |
每个“长度字段 + 内容”都被精确消费,循环结束后解码完成。
下图把上面 2 个步骤串成流程,并逐步演示:


C++
class Codec {
public:
// Encodes a list of strings to a single string.
string encode(vector<string>& strs) {
string out;
for (const string& s :本篇为付费内容
您已阅读试读部分,购买后即可解锁全文。
⚠️ 本站内容已做唯一性标记并受版权保护,未经授权禁止转载,侵权必究。
还没有评论,来说两句?