码迷,mamicode.com
首页 > 其他好文 > 详细

[LintCode] Strings Serialization

时间:2017-06-18 10:44:35      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:origin   ext   tco   parse   like   ngui   imp   blank   scan   

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 

 

 

[LintCode] Strings Serialization

标签:origin   ext   tco   parse   like   ngui   imp   blank   scan   

原文地址:http://www.cnblogs.com/lz87/p/7027290.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!