[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;
    }

 

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