• [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 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 

  • 相关阅读:
    发布spring cloud + vue项目
    以太坊上发行ERC20代币
    [转]大白话讲解Promise(一)
    比特币测试网络搭建
    非对称加密, 助记词, PIN, WIF
    搭建EOS未完
    [转]EOS智能合约 & 私链激活 & 基本操作
    [转]https://www.jianshu.com/p/06443248f4d8
    web3js 进行转账
    [转]How to Send Ethereum with Web3.js and Node
  • 原文地址:https://www.cnblogs.com/lz87/p/7027290.html
Copyright © 2020-2023  润新知