女友跟我說「愛你愛你」,我首先想到的竟是「迴文數」!

女友跟我說「愛你愛你」,我首先想到的竟是「迴文數」!
今天是2020年02月02日,傳說中千年一遇的徹底對稱日。同時,2020又諧音「愛你愛你」。在如此特殊的日子裏,你難道不想幹點什麼嗎?固然,專家建議疫情期間少出門。程序員

當女友早上興沖沖地跟我說 「今天是20200202」 的時候,個人第一反映居然是!面試

這不是個迴文數嗎?而後腦子裏開始快速閃過一段又一段諱莫如深的代碼...算法

emmmm......別問我爲何能有女友!數組

01
迴文數ide

Leetcode 09 迴文數
判斷一個整數是不是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是同樣的整數。好比20200202就是一個迴文數。函數

判斷迴文數有三種解法:code

1 通常解法
將整數轉爲字符串,而後將字符串分割爲數組,經過循環數組的一半長度進行判
斷對應的元素是否相等。
(代碼略)blog

2 除法操做
經過取整和取餘操做得到整數中對應的數字進行比較。遊戲

舉個例子:20200202 這個數字。
經過計算 20200202 / 1000000, 得首位2
經過計算 20200202 % 10000000, 可得末位 2
將首位和末位進行比較,再將第2位0和倒數第2位0取出來繼續比較。遊戲開發

代碼:```

class Solution {
public:
bool isPalindrome(int x) {
//邊界判斷
if (x < 0) return false;
int div = 1;
//
while (x / div >= 10) div *= 10;
while (x > 0) {
int left = x / div;
int right = x % 10;
if (left != right) return false;
x = (x % div) / 10;
div /= 100;
}
return true;
}
};

3 對摺解法

取出後半段數字進行翻轉,看與前半段數字是否相同。
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0 || (x % 10 == 0 && x != 0)) return false;
int revertedNumber = 0;
while (x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
return x == revertedNumber || x == revertedNumber / 10;
}
};

02
最長迴文子串

Leetcode 5 最長迴文子串
給定一個字符串 s,找到 s 中最長的迴文子串。好比"babad"中最長的迴文字串是bab或者aba;好比「cbbd」中最長的迴文字串是bb。

求最長迴文字串的解法有不少,這裏主要介紹四種。

1 暴力解法
列舉全部的子串,判斷是否爲迴文串,保存最長的迴文串。

時間複雜度:兩層 for 循環 O(n²)O(n²),for 循環裏邊判斷是否爲迴文 O(n)O(n),因此時間複雜度爲O(n³)O(n³)。這個複雜度太嚇人了,寫出來面試官可能就會溜了。
空間複雜度:O(1)O(1),常數個變量。
(代碼略)

2 動態規劃
重點是可以列舉初始狀態:

dp[i][i]=1; //單個字符是迴文串
dp[i][i+1]=1 若是 s[i]=s[i+1]; //連續兩個相同字符是迴文串

代碼:
class Solution {
public:
string longestPalindrome(string s) {
int len=s.size();
if(len==0||len==1)
return s;
int start=0;//迴文串起始位置
int max=1;//迴文串最大長度
vector<vector<int>> dp(len,vector<int>(len));//定義二維動態數組
for(int i=0;i<len;i++)//初始化狀態
{
dp[i][i]=1;
if(i<len-1&&s[i]==s[i+1])
{
dp[i][i+1]=1;
max=2;
start=i;
}
}
for(int l=3;l<=len;l++)//l表示檢索的子串長度,等於3表示先檢索長度爲3的子串
{
for(int i=0;i+l-1<len;i++)
{
int j=l+i-1;//終止字符位置
if(s[i]==s[j]&&dp[i+1][j-1]==1)//狀態轉移
{
dp[i][j]=1;
start=i;
max=l;
}
}
}
return s.substr(start,max);//獲取最長迴文子串
}
};

3 中心擴展法
迴文中心的兩側互爲鏡像。所以,迴文能夠從他的中心展開,而且只有 2n-1 個這樣的中心(一個元素爲中心的狀況有 n 個,兩個元素爲中心的狀況有 n-1 個)

代碼:```

class Solution {
public:
    string longestPalindrome(string s) {
        int len=s.size();
        if(len==0||len==1)
            return s;
        int start=0;//記錄迴文子串起始位置
        int end=0;//記錄迴文子串終止位置
        int mlen=0;//記錄最大回文子串的長度
        for(int i=0;i<len;i++)
        {
            int len1=expendaroundcenter(s,i,i);//一個元素爲中心
            int len2=expendaroundcenter(s,i,i+1);//兩個元素爲中心
            mlen=max(max(len1,len2),mlen);
            if(mlen>end-start+1)
            {
                start=i-(mlen-1)/2;
                end=i+mlen/2;
            }
        }
        return s.substr(start,mlen);
        //該函數的意思是獲取從start開始長度爲mlen長度的字符串
    }
private:
    int expendaroundcenter(string s,int left,int right)
    //計算以left和right爲中心的迴文串長度
    {
        int L=left;
        int R=right;
        while(L>=0 && R<s.length() && s[R]==s[L])
        {
            L--;
            R++;
        }
        return R-L-1;
    }
};

4 Manacher(馬拉車) 算法
Manacher 算法本質上仍是中心擴散法,只不過它使用了相似 KMP 算法的技巧,充分挖掘了已經進行迴文斷定的子串的特色,在遍歷的過程當中,記錄了已經遍歷過的子串的信息,也是典型的以空間換時間思想的體現。

該算法的推理過程比較複雜,下次能夠再寫一篇文章來詳細介紹。這裏只是甩出代碼。```

class Solution {
private:
int centerSpread(string s, int center) {
int len = s.size();
int i = center - 1;
int j = center + 1;
int step = 0;
while (i >= 0 && j < len && s[i] == s[j]) {
i--;
j++;
step++;
}
return step;
}
public:
string longestPalindrome(string s) {
// 特判
int size = s.size();
if (size < 2) {
return s;
}
// 獲得預處理字符串
string str = "#";
for (int i = 0; i < s.size(); ++i) {
str += s[i];
str += "#";
}
int sSize = 2 * size + 1;
int maxLen = 1;

int start = 0;
    for (int i = 0; i < sSize; i++) {
        int curLen = centerSpread(str, i);
        if (curLen > maxLen) {
            maxLen = curLen;
            start = (i - maxLen) / 2;
        }
    }
    return s.substr(start, maxLen);
}

};

03
2020愛你愛你

思緒從20200202轉到迴文數再到迴文序列判斷,已然不能再深刻下去了,不然或許會迎來女友的公開審問。

今年開年實在是有太多讓人感慨無奈又憂心忡忡的事情了,好在至少還有今天這麼個日子。雖說不上多重要,可是可以聽到最愛的人看似隨意而又深情滿滿的告白,不也是件樂事嘛。

固然了,單身的朋友坐等國家分配就好。而後等下一個千年一遇的日子哈。

最後但願疫情早日結束!

![](https://s4.51cto.com/images/blog/202007/29/6e4fbb4933a6bb40a2f0ff999e25fa16.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

掃個關注,有空來看看直男程序員的業餘分享。
![](https://s4.51cto.com/images/blog/202007/29/5a5f4d51f03e244b600cb471ddc18f80.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

推薦閱讀(點擊下方連接便可閱讀)

苦逼研究生的幸運求職路
新冠肺炎肆虐,不如在家練練基礎算法 | 鏈表篇
建議簡歷寫很差的同窗進來瞧一瞧~
非科班如何經過業餘時間自學遊戲開發,最終收穫騰訊網易offer
面試高頻算法詳解-LRU
生物專業女生教你準備兩個月簽約AI獨角獸
想成爲BAT後臺開發工程師,這些是基礎!

Amazing10
承蒙厚愛。
相關文章
相關標籤/搜索