[LintCode] Strings Serialization

Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.

Please implement encode and decode

Example

Given strs = ["lint","code","love","you"]
string encoded_string = encode(strs)

return `["lint","code","love","you"]` when you call decode(encoded_string)

Solution 1. Application of escape sequence

A straightforward idea is to add ";" between two strings as the divide symbol. But the problem here is,

what about if the input strings contain ";" already? How do we distinguish between the divide symbol ";"

and the ";" that are part of the input strings?

Consider how escape sequence works. \ represents the start of an escape sequence, like \n is a newline

character. Since \ is already reserved as the start of any escape sequence, \\ is used to represent the

backslash literal. We can simply borrow this idea and use it in this problem.

Let‘s define : as the start of escape sequence, so :; is our divide symbol now.

Encode:  Replace all : with :: in each string, so :: represents the original : literal;

       Connect each string with divide symbol :;

Decode: Scan from left to right until a : is met.

     If the next character is ;, it means we have a :; divide symbol;

      If not, since we‘ve already replaced all : with :: in encoding, so

      we know that we just saw a : literal.

 1 public class Solution {
 2     public String encode(List<String> strs) {
 3         if(strs == null){
 4             return null;
 5         }
 6         if(strs.size() == 0){
 7             return ":;";
 8         }
 9         StringBuffer sb = new StringBuffer();
10         for(String s : strs){
11             String newStr = s.replaceAll(":", "::");
12             sb.append(newStr);
13             sb.append(":;");
14         }
15         return sb.toString();
16     }
17     public List<String> decode(String str) {
18         if(str == null){
19             return null;
20         }
21         List<String> strs = new ArrayList<String>();
22         int idx = 0;
23         StringBuffer sb = new StringBuffer();
24         while(idx < str.length()){
25             if(str.charAt(idx) != ‘:‘){
26                 sb.append(str.charAt(idx));
27                 idx++;
28             }
29             else if(str.charAt(idx + 1) == ‘;‘){
30                 strs.add(sb.toString());
31                 idx += 2;
32                 sb = new StringBuffer();
33             }
34             else{
35                 sb.append(":");
36                 idx += 2;
37             }
38         }
39         return strs;
40     }
41 }

Solution 2. Attach each string‘s length as a prefix

Encode: add String.valueOf(str.length()) + ‘$‘ as a prefix to each string; ‘$‘ is the divide symbol between each string‘s length and

    the string itself.

Q: Can we add each string‘s length as a suffix?

A: No, we can‘t. If we add as suffix and the string already contains $, we won‘t be able to get the right length info.

Add as prefix does not have this problem as the very first time we see a $, we know the length info is right prior to this $.

 1 public class Solution {
 2     /**
 3      * @param strs a list of strings
 4      * @return encodes a list of strings to a single string.
 5      */
 6     public String encode(List<String> strs) {
 7         // Write your code here
 8         StringBuilder result = new StringBuilder();
 9         for(String str : strs){
10             result.append(String.valueOf(str.length()) + "$");
11             result.append(str);
12         }
13         return result.toString();
14     }
15
16     /**
17      * @param str a string
18      * @return dcodes a single string to a list of strings
19      */
20     public List<String> decode(String str) {
21         // Write your code here
22         List<String> result = new LinkedList<String>();
23         int start = 0;
24         while(start < str.length()){
25             int idx = str.indexOf(‘$‘, start);
26             int size = Integer.parseInt(str.substring(start, idx));
27             result.add(str.substring(idx + 1, idx + size + 1));
28             start = idx + size + 1;
29         }
30         return result;
31     }
32 }

Runtime: Both solutions have a runtime of O(n * k), n is the number of strings, k is the average number of characters in each string.

Related Problems

Binary Tree Serialization

时间: 2024-10-13 09:11:10

[LintCode] Strings Serialization的相关文章

Lintcode: Serialization and Deserialization Of Binary Tree

Design an algorithm and write code to serialize and deserialize a binary tree. Writing the tree to a file is called 'serialization' and reading back from the file to reconstruct the exact same binary tree is 'deserialization'. There is no limit of ho

[lintcode easy]Compare Strings

Compare Strings Compare two strings A and B, determine whether A contains all of the characters in B. The characters in string A and B are all Upper Case letters. Example For A = "ABCD", B = "ACD", return true. For A = "ABCD"

lintcode 中等题:binary tree serialization 二叉树的序列化和反序列化

题目 二叉树的序列化和反序列化 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构. 样例 给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7},表示如下的树结构: 3 / 9 20 / 15 7 我们的数据是进行BFS遍历得到的.当你测试结果wrong answer时,你可以作为输

lintcode 容易题:Compare Strings 比较字符串

题目: 比较字符串 比较两个字符串A和B,确定A中是否包含B中所有的字符.字符串A和B中的字符都是 大写字母 样例 给出 A = "ABCD" B = "ACD",返回 true 给出 A = "ABCD" B = "AABC", 返回 false 注意 在 A 中出现的 B 字符串里的字符不需要连续或者有序. 解题: 用数组,或者用HashMap都可以,由于char String转换成Integer不是很熟悉,搞了好久...

LintCode: Compare Strings

C++ 1 class Solution { 2 public: 3 /** 4 * @param A: A string includes Upper Case letters 5 * @param B: A string includes Upper Case letter 6 * @return: if string A contains all of the characters in B return true 7 * else return false 8 */ 9 bool com

LintCode Two Strings Are Anagrams

1. 把string变为char数组 2. 排序Arrays.sort() public class Solution { /** * @param s: The first string * @param b: The second string * @return true or false */ public boolean anagram(String s, String t) { if(s == null || t == null) return false; if(s.length(

LintCode &quot;Binary Tree Serialization&quot;

Here is a BFS solution which is compatible with LeetCode binary tree format. class Solution { public: /** * This method will be invoked first, you should design your own algorithm * to serialize a binary tree which denote by a root node to a string w

Lintcode7 Binary Tree Serialization solution 题解

[题目描述] Design an algorithm and write code to serialize and deserialize a binary tree. Writing the tree to a file is called 'serialization' and reading back from the file to reconstruct the exact same binary tree is 'deserialization'. 设计一个算法,并编写代码来序列化

Lintcode 9.Fizz Buzz 问题

------------------------ AC代码: class Solution { /** * param n: As description. * return: A list of strings. */ public ArrayList<String> fizzBuzz(int n) { ArrayList<String> results = new ArrayList<String>(); for (int i = 1; i <= n; i++