encode-and-decode-strings
class Codec {
// 编码字符串列表
encode(strs: string[]): string {
return strs.map(str => `${str.length}#${str}`).join('');
}
// 解码字符串
decode(s: string): string[] {
const result: string[] = [];
let i = 0;
while (i < s.length) {
// 找到 '#' 分隔符的位置
const delimiterIndex = s.indexOf('#', i);
// 解析字符串长度
const length = parseInt(s.slice(i, delimiterIndex), 10);
// 提取实际字符串
const str = s.slice(delimiterIndex + 1, delimiterIndex + 1 + length);
result.push(str);
// 移动索引到下一个字符串的开始位置
i = delimiterIndex + length + 1 ;
}
return result;
}
}
// 时间复杂度:
// - encode: O(n),其中 n 是所有字符串的总长度
// - decode: O(n),其中 n 是编码后字符串的长度
// 空间复杂度:O(n),用于存储编码或解码后的结果
// 测试用例
const codec = new Codec();
console.log(codec.decode(codec.encode(["Hello", "World"]))); // ["Hello", "World"]
console.log(codec.decode(codec.encode([""]))); // [""]
console.log(codec.decode(codec.encode(["", ""]))); // ["", ""]
console.log(codec.decode(codec.encode(["a", "b", "c"]))); // ["a", "b", "c"]
console.log(codec.decode(codec.encode(["Hello", "World", "!"]))); // ["Hello", "World", "!"]
这个实现使用了以下的数组和哈希思想:
-
编码时,我们使用了数组的
map
方法来转换每个字符串,然后用join
方法将它们连接起来。 -
在编码的过程中,我们为每个字符串添加了长度信息,这类似于哈希表中的键值对概念,其中长度作为"键",实际字符串作为"值"。
-
解码时,我们使用一个数组
result
来存储解码后的字符串。 -
解码过程中,我们遍历编码后的字符串,这类似于遍历数组或哈希表。我们解析每个字符串的长度(类似于读取哈希表的键),然后提取相应长度的字符串(类似于读取哈希表的值)。
s = "5#Hello5#World"
^
i (初始位置)
1. 第一次迭代:
5#Hello5#World
^^
idelimiterIndex
length = 5
str = "Hello"
7 next i
6 delimiterIndex+5 => end of this word
1 delimiterIndex
01234567
5#Hello5#World
^
i (下一次迭代的起始位置)
2. 第二次迭代:
5#Hello5#World
^^
idelimiterIndex
length = 5
str = "World"
5#Hello5#World
^
i (循环结束,因为 i >= s.length)