LeetCode58.最後一個單詞的長度(C++實現)
阿新 • • 發佈:2018-12-12
問題如下
剛看這道題目以為很簡單,直接呼叫C++的rfind()函式,以為幾行程式碼就可以搞定,結果發現,測試用例太刁鑽了,各種測試用例想不到的情況。比如以下這些測試用例:
" ab "
"a"
"a "
""
" "
" "
沒辦法,只能採用最有效的方法——遍歷字串,將所有單詞全部分離出來,程式碼如下:
//方法一:遍歷字串,分離出所有單詞 int lengthOfLastWord(string s) { if(s.empty()) return 0; //如果字串為空,直接返回0 vector<string> word; //將s中的單詞一個一個拆出來放到容器word中 int begin, lenWord = 0; //begin用於記錄一個單詞首字母的位置,lenWord記錄單詞的長度 for (int i = 0; i < s.size(); i++) { if((i == 0 && s[i] != ' ') || (i != 0 && s[i - 1] == ' ' && s[i] != ' ')) { //一個單詞首字母的開始有兩種情況:1、字串開始位置就是一個字母;2、一個單詞前面是一個空格 begin = i; lenWord++; if(i == s.size() - 1) //字串中只有一個字元 { word.push_back(s.substr(begin, lenWord)); break; } }else if(s[i] != ' ' && i != s.size() - 1){ //如果不是前面的情況,而且該字元又不是空格,那它必然是某個單詞的字元,注意考慮是不是字串最後一個位置 lenWord++; }else if(i != 0 && s[i - 1] != ' ' && s[i] == ' '){ //如果當前字元為空格,而且上一個不為空格,那麼意味著一個單詞已經拆分出來了,i!=0是為了防止下標越界 word.push_back(s.substr(begin, lenWord)); lenWord = 0; }else if(s[i] != ' ' && i == s.size() -1){ //拆分某個單詞的時候,字串突然結束的情況 word.push_back(s.substr(begin, lenWord + 1)); } } //打印出所有單詞 /*cout << "word:" << endl; for (int j = 0; j < word.size(); j++) { cout << word[j] << endl; } cout << endl;*/ if(word.empty()) //如果word為空,說明沒有單詞拆出來 return 0; else //如果不為空,返回最後一個元素的長度 return word[word.size() - 1].size(); }
上面的演算法雖然是線性時間複雜度,但是使用了陣列空間,我們可以在遍歷字串的時候只記錄最後一個單詞的長度就好;基本思路是:如果當前遍歷的字元不是空格就計數值加一,如果當前遍歷的字元為空格同時下一個字元不是空格就計數值清零。程式碼如下:
//方法二:遍歷字串,將最後一個單詞的長度計算出來就好 int lengthOfLastWord(string s) { int countWord = 0; //用於記錄單詞的長度 for (int index = 0; index < s.size(); index++) { if(s[index] == ' ') { if(index != s.size() - 1 && s[index + 1] != ' ') { // 當前為空格,下一個不是空格,那麼countWord需要清零,重新計算 countWord = 0; continue; } else continue; } countWord++; //當前不是空格就加一 } return countWord; }