1. 程式人生 > 其它 >Leetcode——陣列和字串

Leetcode——陣列和字串

技術標籤:資料結構leetcode

151.翻轉字串裡的單詞

給定一個字串,逐個翻轉字串中的每個單詞。

說明

  • 無空格字元構成一個 單詞 。
  • 輸入字串可以在前面或者後面包含多餘的空格,但是反轉後的字元不能包括。
  • 如果兩個單詞間有多餘的空格,將反轉後單詞間的空格減少到只含一個。
    示例

提示:

  • 1 <= s.length <= 104
  • s 包含英文大小寫字母、數字和空格 ’ ’
  • s 中 至少存在一個 單詞

思路:

  • 要原地進行翻轉的話,就不能另外建立一個字串來從後往前讀取儲存單詞。
  • 可以先將字串整個翻轉,然後再在每個單詞內進行翻轉。
  • 程式碼為官方題解提供的C++程式碼,程式碼很簡短但是設計非常妙,妙到我看了兩天並且在餘某同學的幫助下才看懂(勉強看懂)。
  • 巧妙的點在於充分利用索引下標,避開了字串兩端以及單詞中間多餘的空格,直接在原字串空間中進行修改,而不用再建立一個,空間效率為O(1),時間效率上也是秒殺了91%的人,很強,感覺學到了新的思路。
class Solution {
public:
    string reverseWords(string s) {
        // 反轉整個字串
        reverse(s.begin(), s.end());

        int n = s.size();
        int idx = 0;//利用新索引idx直接在原字串上進行修改,以及作為找到的每個單詞的末端索引
        
        for
(int start = 0; start < n; ++start) { //只有s[start]為非空格時才開始執行,這樣就能避開前面的空格 if (s[start] != ' ') { // 第一次進入if時,還沒有讀到過單詞,idx為0,此時不用在前面補空格 //之後再進入if的時候,已經讀到了一個完整單詞,單詞後面應該有一個空格,此時idx處填一個空白字元,然後將idx移動到下一個單詞的開頭位置 if (idx != 0) s[
idx++] = ' ';//單詞之間的空格 // 從非空格字元s[start]開始,迴圈遍歷至單詞的末尾 int end = start; while (end < n && s[end] != ' ') //這裡是在找字串中屬於單詞的部分,當s[end]為空格時暫停遍歷,一輪遍歷得到的是一個完整單詞 //將end遍歷到的每個字元以idx儲存 s[idx++] = s[end++]; //以上工作相當於將原字串前後兩端以及中間多餘的空格捨去後重新儲存,並且使用的是原字串空間,沒有另創空間。 // 反轉整個單詞 //reverse函式用於反轉在[first,last)範圍內的順序 //(包括first指向的元素,不包括last指向的元素),reverse函式無返回值 reverse(s.begin() + idx - (end - start), s.begin() + idx); // 更新start,去找下一個單詞,此時的s[end]是空格 //進行下一輪的時候同樣,會先避開下一個單詞之前的空格,只有s[start]非空格時才會進入if,開始遍歷單詞 start = end; } } s.erase(s.begin() + idx, s.end()); return s; } };