1. 程式人生 > >21 字串專題:第一個只出現一次的字元

21 字串專題:第一個只出現一次的字元

0 引言

題目:在一個字串(0<=字串長度<=10000,全部由字母組成)中找到第一個只出現一次的字元,並返回它的位置, 如果沒有則返回 -1(需要區分大小寫).

1 抽象問題具體化

舉例:返回字串 “google”中第一個只出現一次的字元,如果沒有則返回-1.

解答:1. 遍歷字串,訪問g,++ myStr['g' - 'A'] ,儲存第一個g出現的位置, position['g' - 'A'];

   2. 繼續訪問其他字元, ++ myStr[str[i] - 'A'],儲存第一個str[i]出現的位置, position[str[i] - 'A']; 

   3. 遍歷myStr和position,找到mystr[i] == 1的最小的position的值,即為google中第一個只出現一次的字元,為 'l' .

2 具體問題抽象分析

(1)定義兩個整型陣列, myStr, positon, 並resize 為 size = 'z' - 'A' + 1 這麼大

(2)遍歷字串,儲存每個字元出現的次數至myStr, 儲存每個字元初次出現的位置到 position

(3)遍歷myStr 和position,尋找myStr[i] == 1 的位置最靠前的字元,即position[i]最小 , 儲存在firstOnlyPosition中

(4)如果firstOnlyPosition == 初始值,則返回-1;否則,返回firstOnlyPosition作為結果輸出.

3 demo

/* FirstNotRepeatingChar: 尋找字串中第一個不重複出現的字元
* 輸入引數:字串
* 輸出引數:該字元在字串中的位置
* 採用的演算法核心思想: 兩次遍歷找到結果
    1. 第一次遍歷字串時,儲存每個相同字元出現的次數和首次出現的位置;
    2. 第二次遍歷字串時,尋找只出現過一次的字元中,出現位置最早的字元,返回結果即可
* 演算法的複雜度:O(n + k),k為不重複字元出現的次數
*/
int
FirstNotRepeatingChar(string str) { vector<int> myStr, position; const int size = 'z' - 'A' + 1; myStr.resize(size), position.resize(size);
for(int i=0; i<str.size(); i++){ ++ myStr[str[i]-'A']; if(myStr[str[i]-'A'] == 1) position[str[i]-'A'] = i; } int firstOnlyPosition = str.size(); for(int i=0;i<size;i++){ if(myStr[i] == 1 && position[i] < firstOnlyPosition) firstOnlyPosition = position[i]; } if(firstOnlyPosition == str.size()) return -1; else return firstOnlyPosition; }

4 程式碼優化

暫時還沒有找到更好的演算法,以後再說吧