1. 程式人生 > 其它 >[雙指標] [讀寫指標][ 字串/資料 壓縮] 443. 壓縮字串

[雙指標] [讀寫指標][ 字串/資料 壓縮] 443. 壓縮字串


昨天面試,第一道題A的太快,結果面試官直接說這麼快呀,那麼來第二道。由此可見,即使能默寫,你也要裝作思考一番的樣子,在寫出來。

說回正題,此題的方法採用的 是帆哥的程式碼。我只是在他的程式碼上加以我的理解註釋

主要思想:

  • 讀指標在前面讀,記錄讀指標開始的位置,然後記錄他們之間的距離。也就是重複字元的個數
  • 寫指標在後面寫,寫的時候還要注意,如果大於10,那麼肯定取個位來獲取全部的數值。那麼就寫反了,比如13,就寫成了31
  • 因此需要在翻轉一下。
  • 題目思想是比較簡單的。
  • 但是要注意一下細節問題。
class Solution {
    public int compress(char[] chars) {
        int write= 0;
        int read = 0 ;
        int len = chars.length;
        while(read<len)
        {
            int readStart = read;
            // 寫指標往前走,一直走到不重複的字元為止
            while(read+1<len&&chars[read+1]==chars[read])
            {
                read++;
            }
            //  ...  [readStart... read]...
            // 前面讀後面寫。 也就是說,aaa . a是3個,應該攜程a3 ,但是寫需要先寫a,
            // 然後記錄到底幾個a,接下來的操作就是計算到底幾個a
            chars[write++] = chars[readStart];
            // 如果相等,就說只有這一個字元,一個字元不用記錄數量的
            if(readStart!=read)
            {
                // 記錄開始點以及結束點 之間的距離
                int count = read - readStart+1;
                // 寫指標開始點,寫指標結束點,比如 寫 a:  123
                // 1所在的位置就是開始點,3就是結束點。
                int writeStart = write;
                while(count!=0)
                {
                    // 因為如果a是13個,那麼我需要先寫1 ,在寫3,但是我需要把整形轉換為字元
                    // 因此需要這樣做;
                    chars[write++] = (char)(count%10+'0');
                    count/=10;
                }
                //為什麼需要這個? 因為我是13,我13寫的時候先得到個位,然後得到十位,
                //寫的時候就是寫成了 31, 但是資料次數是13,因此需要把31重新翻轉為13.
                reverse(chars,writeStart,write-1);
            }
            // a:13 寫完了,需要寫b了。
            read++;

        }
        return write;

    }
    public void reverse(char[] chars,int start,int end)
    {
        while(start<end)
        {
            char temp = chars[start];
            chars[start]= chars[end];
            chars[end] =temp;

            start++;
            end--;
        }
    }
}