[Leetcode]271. Encode and Decode Strings

嗯,这一题主要是为了保证encode和decode的唯一性,我面google的时候遇到过,当时面试官给的提示很简单,随便定义一个字符为分隔符,字符串之间用分隔符定义开来,如果遇到分隔符就变成两个。举个例子,如果你拿逗号来做分隔符。
那么"ab", "b,b", "d,b,ee" encode之后就会变成"ab,b,,b,d,,b,,ee,",decode也很简单,遇到单个逗号就表示一个字符串终结了开始新的字符串,遇到偶数个逗号就表示真的遇到了一个逗号。所以decode下来,就变成"ab", "b,b", "d,b,ee",就和原来encode之前是一样的了。

这个做法咋看上去是对的,当时我也是这么做的,面试官也没说啥表示通过了,通过了,过了,了.....

但实际上这种做法并不对,不完全对。举个例子,"a,","b"或者"a",",b" encode之后都会变成"a,,,b"。但是你decode的时候却没有办法区分开来。这就失去了唯一性了。同样的,连续两个空字符串也会让这种做法露出马脚。",,"。这样就会变成一个逗号的字符串。
所以我们要引入一个新的字符作为分隔符的辅助字符,譬如感叹号"!"。这样,当遇到","的时候,原本的做法是把它变成",,"。现在就变成",!"。然后遇到感叹号自己的时候就变为"!!"。这样,就不会出现因为连续逗号而形成的混乱局面。同样的,连续的感叹号也不会形成混乱局面,因为一旦出现逗号,只需要判断后面的连续感叹号的数目是奇数还是偶数,如果是偶数,那么当前的逗号肯定就是一个分隔符。后面的感叹号是下一个原字符串的感叹号所形成的。如果是奇数,那么第一个原字符是逗号翻译而成的“,!”,后面的感叹号则是原字符串的感叹号转义而成的。
根据上述描述,可以得到代码如下:

    // Encodes a list of strings to a single string.
    public String encode(List<String> strs) {
        StringBuilder sb = new StringBuilder();
        for (String str : strs) {
            char[] chArr = str.toCharArray();
            for (char ch : chArr) {
                switch(ch) {
                    case ',' : 
                        sb.append(",!");
                        break;
                    case '!' :
                        sb.append("!!");
                        break;
                    default:
                        sb.append(ch);
                        break;
                }
            }
            sb.append(",");
        }

        return sb.toString();
    }

    // Decodes a single string to a list of strings.
    public List<String> decode(String s) {
        List<String> result = new LinkedList<String>();
        StringBuilder sb = new StringBuilder();
        char[] chArr = s.toCharArray();
        for (int i = 0; i < chArr.length; i++) {
            if (chArr[i] == ',') {
                int cursor = i + 1;
                while (cursor < chArr.length && chArr[cursor] == '!') {
                    cursor++;
                }

                if ((cursor - i) % 2 == 1) {
                    result.add(sb.toString());
                    sb.delete(0, sb.length());
                } else {
                    sb.append(',');
                    i++;
                }
                
                for (int j = i + 1; j < cursor; j += 2) {
                    sb.append('!');
                }
                i = cursor - 1;
            } else if (chArr[i] == '!') {
                sb.append('!');
                i++;
            } else {
                sb.append(chArr[i]);
            }
        }
        
        return result;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章