首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

演算法面試必考:字串原地反轉的兩種 O(1) 空間實現

     編輯:關於C

題目

給定一個以空字元結尾的字元陣列 char *str,要求原地反轉字串,時間複雜度 O(n),額外空間 O(1)。

方法一:異或交換法

利用 a ^= b; b ^= a; a ^= b; 無需暫存變數即可交換兩值。

char *reverse_xor(char *str) {
    if (!str) return NULL;
    size_t len = strlen(str);
    for (size_t i = 0, j = len - 1; i < j; ++i, --j) {
        str[i] ^= str[j];
        str[j] ^= str[i];
        str[i] ^= str[j];
    }
    return str;
}
  • 優點:零暫存變數,程式碼極短。
  • 缺點:現代 CPU 流水線對異或指令優化較差;若 i == j(中間字元)會將字元歸零,迴圈條件 i < j 已避免。
  • 適用場景:嵌入式極度受限環境、面試展示位運算技巧。

方法二:雙指標對調法

傳統雙指標從頭尾向中間逼近,使用單一 char tmp 暫存。

char *reverse_swap(char *str) {
    if (!str) return NULL;
    size_t len = strlen(str);
    for (size_t i = 0, j = len - 1; i < j; ++i, --j) {
        char tmp = str[i];
        str[i] = str[j];
        str[j] = tmp;
    }
    return str;
}
  • 優點:編譯器易優化為 xchg 指令或向量化;可讀性最佳;無位運算副作用。
  • 缺點:需 1 byte 暫存(可忽略)。
  • 推薦:生產環境首選。

進階:避免重複呼叫 strlen

若函數介面已知長度,直接傳入 len 避免 O(n) 掃描:

void reverse_n(char *str, size_t len) {
    for (size_t i = 0, j = len - 1; i < j; ++i, --j) {
        char tmp = str[i];
        str[i] = str[j];
        str[j] = tmp;
    }
}

效能實測

長度XOR (ns)Swap (ns)優勢
104538Swap ~15%
10003,2002,700Swap ~16%
1,000,0003.1 ms2.6 msSwap ~16%

測試環境:Intel i7-12700K, GCC 12.2 -O3。Swap 穩定快 15% 左右。

常見錯誤

  1. for (i=0; i<len; i++) swap(str[i], str[len-1-i]):會交換兩次導致原樣,且中間字元自我 XOR 歸零。
  2. 忘記檢查 str == NULL。
  3. 對字串常量 char *s = "abc"; reverse(s); 導致段錯誤(常量區唯讀)。

總結

字串原地反轉是考驗指標操作、迴圈邊界、位運算理解的經典題目。雙指標 + 暫存變數是工程上最穩健、效能最佳、可讀性最高的選擇;XOR 交換適合面試展示位運算功力或極度受限環境。切記:不要為了省 1 byte 暫存犧牲可讀性與效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved