## 題目描述
回文,英文palindrome,指一個順著讀和反過來讀都一樣的字符串,比如madam、我愛我,這樣的短句在智力性、趣味性和藝術性上都頗有特色,中國歷史上還有很多有趣的回文詩。
那么,我們的第一個問題就是:判斷一個字串是否是回文?
## [](https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.04.md#分析與解法)分析與解法
回文判斷是一類典型的問題,尤其是與字符串結合后呈現出多姿多彩,在實際中使用也比較廣泛,而且也是面試題中的常客,所以本節就結合幾個典型的例子來體味下回文之趣。
### [](https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.04.md#解法一)解法一
同時從字符串頭尾開始向中間掃描字串,如果所有字符都一樣,那么這個字串就是一個回文。采用這種方法的話,我們只需要維護頭部和尾部兩個掃描指針即可。
代碼如下::
~~~
bool IsPalindrome(const char *s, int n)
{
//非法輸入
if (s == NULL || n < 1)
return false;
char *front, *back;
//初始化頭指針和尾指針
front = s;
back = s + n - 1;
while (front < back)
{
if (*front != *back)
return false; // 不是回文,立即返回
++front;
--back;
}
return true; // 是回文
}
~~~
這是一個直白且效率不錯的實現,時間復雜度:O(n),空間復雜度:O(1)。
### [](https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.04.md#解法二)解法二
上述解法一從兩頭向中間掃描,那么是否還有其它辦法呢?我們可以先從中間開始、然后向兩邊擴展查看字符是否相等。參考代碼如下:
~~~
bool IsPalindrome2(const char *s, int n)
{
if (s == NULL || n < 1)
return false; // 非法輸入
char *first, *second;
int m = ((n >> 1) - 1) >= 0 ? (n >> 1) - 1 : 0; // m is themiddle point of s
first = s + m;
second = s + n - 1 - m;
while (first >= s)
if (s[first--] != s[second++])
return false; // not equal, so it's not apalindrome
return true; // check over, it's a palindrome
}
~~~
時間復雜度:O(n),空間復雜度:O(1)。
雖然本解法二的時空復雜度和解法一是一樣的,但很快我們會看到,在某些回文問題里面,這個方法有著自己的獨到之處,可以方便的解決一類問題。
## [](https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.04.md#舉一反三)舉一反三
1、判斷一條單向鏈表是不是“回文”
分析:對于單鏈表結構,可以用兩個指針從兩端或者中間遍歷并判斷對應字符是否相等。但這里的關鍵就是如何朝兩個方向遍歷。由于單鏈表是單向的,所以要向兩個方向遍歷的話,可以采取經典的快慢指針的方法,即先位到鏈表的中間位置,再將鏈表的后半逆置,最后用兩個指針同時從鏈表頭部和中間開始同時遍歷并比較即可。
2、判斷一個棧是不是“回文”
分析:對于棧的話,只需要將字符串全部壓入棧,然后依次將各字符出棧,這樣得到的就是原字符串的逆置串,分別和原字符串各個字符比較,就可以判斷了。
- 關于
- 第一部分 數據結構
- 第一章 字符串
- 1.0 本章導讀
- 1.1 旋轉字符串
- 1.2 字符串包含
- 1.3 字符串轉換成整數
- 1.4 回文判斷
- 1.5 最長回文子串
- 1.6 字符串的全排列
- 1.10 本章習題
- 第二章 數組
- 2.0 本章導讀
- 2.1 尋找最小的 k 個數
- 2.2 尋找和為定值的兩個數
- 2.3 尋找和為定值的多個數
- 2.4 最大連續子數組和
- 2.5 跳臺階
- 2.6 奇偶排序
- 2.7 荷蘭國旗
- 2.8 矩陣相乘
- 2.9 完美洗牌
- 2.15 本章習題
- 第三章 樹
- 3.0 本章導讀
- 3.1 紅黑樹
- 3.2 B樹
- 3.3 最近公共祖先LCA
- 3.10 本章習題
- 第二部分 算法心得
- 第四章 查找匹配
- 4.1 有序數組的查找
- 4.2 行列遞增矩陣的查找
- 4.3 出現次數超過一半的數字
- 第五章 動態規劃
- 5.0 本章導讀
- 5.1 最大連續乘積子串
- 5.2 字符串編輯距離
- 5.3 格子取數
- 5.4 交替字符串
- 5.10 本章習題
- 第三部分 綜合演練
- 第六章 海量數據處理
- 6.0 本章導讀
- 6.1 關聯式容器
- 6.2 分而治之
- 6.3 simhash算法
- 6.4 外排序
- 6.5 MapReduce
- 6.6 多層劃分
- 6.7 Bitmap
- 6.8 Bloom filter
- 6.9 Trie樹
- 6.10 數據庫
- 6.11 倒排索引
- 6.15 本章習題
- 第七章 機器學習
- 7.1 K 近鄰算法
- 7.2 支持向量機
- 附錄 更多題型
- 附錄A 語言基礎
- 附錄B 概率統計
- 附錄C 智力邏輯
- 附錄D 系統設計
- 附錄E 操作系統
- 附錄F 網絡協議