- 題目一:最長連續迴文子串。
- 問題分析:迴文串顧名思義表示前後讀起來都是一樣,這裡面又是需要連續的。分析這個問題的結構,可以想到多種方法。暴力解決的方式,2層迴圈遍歷得出各個子串,然後再去判斷該子串是否迴文,這樣的話O(N)=n的三次方,還有一種是dp解決。
- 解題方法一:暴力解決的方法。前面已經講到了方法,下面給出方法的實現。
class Solution { public: string longestPalindrome(string s) { int maxlength = 0; int start = 0, end = 0; for (int i=0; i<s.size(); i++){ for (int j=i+1; j<s.size(); j++){ int temp1, temp2; for (temp1=i, temp2=j; temp1<temp2; temp1++, temp2--){ if (s[temp1] != s[temp2]) break; } if (temp1>=temp2 && j-i>maxlength){ maxlength = j-i+1; start = i; end = j; } } } if (maxlength > 0) s.substr(start, maxlength); return NULL; } };
- 解題方法二:DP求解。為什麼會想到dp求解呢。首先分析問題。最長連續子串是否迴文。如果一個子串迴文,那麼子串的子串也就是迴文的,依次類推就簡化為一個小的解,從而得到整體的解。
具體思路:設定一個int二維陣列DP[i][j]用來儲存從i到j的串是否迴文,1表示是,0表示否。
這裡有三種情況需要考慮:①:當只有一個字元的時候,i=j,肯定迴文 DP[i][j] = 1;
②:當兩個兩個字元相鄰的時候,如果他們相等,那麼他們也是迴文的,i-j<2 && s[i]==s[j] -> DP[i][j] = 1
③:當超過兩個字元的時候,如果他們首尾是相同的並且除去首尾字元的剩餘字元也是迴文的話,那麼這個串也是迴文的。
s[i] == s[j] && DP[i+1][j-1] = 1 ->DP[i][j] = 1
考慮完這三種情況,就設定兩個指標記錄最長迴文子串的左右位置,然後直接提取出來即可。DP[i][j] = 1 並且最長字元長度小於當前字元長度。 -
class Solution { public: string longestPalindrome(string s) { int dp[s.size()][s.size()] ; int left = 0, right = 0, maxlength = 0; for (int i=0; i<s.size(); i++){ for (int j=0; j<i; j++){ //這裡表示出了所有的情況 //當為相鄰兩個字串時,如果相等則為1,當大於兩個字串時,如果首尾相同並且子串是迴文的話,那麼這個串也是迴文 dp[j][i] = (s[i] == s[j] && ((i-j < 2) || dp[j+1][i-1])); if (dp[j][i] && maxlength< i-j+1) { maxlength = j-i+1; left = j; right = i; } } dp[i][i] = 1;//這裡表示單個字串就是迴文串。 } return s.substr(left, right-left+1); } };
- 問題分析:迴文串顧名思義表示前後讀起來都是一樣,這裡面又是需要連續的。分析這個問題的結構,可以想到多種方法。暴力解決的方式,2層迴圈遍歷得出各個子串,然後再去判斷該子串是否迴文,這樣的話O(N)=n的三次方,還有一種是dp解決。
- 題目二:給出一個整數,判斷這個整數是否是迴文數字,不能使用額外的儲存空間,意思是不能將他變為字串。
- 題目分析:第一想到的就是將他變成一個字串然後對他進行判斷是否是迴文串。但是題目不能變為字串。這裡我們就可以變換一種方法。比如對數字“12321”,12321/10000=1,首位為1, 12321%10=1,尾部為1,然後繼續判斷232這個數字,按照相同的方法(這裡的關鍵是剩餘數字的位數需要確定)
- 程式碼:
class Solution { public: bool isPalindrome(int x) { if (x < 0) return false; int flag = 1; while(x/flag >= 10){//求整數的最高位 -》這是求最高位的位數的技巧 flag *= 10; } while (x) { int left = -1, right = -1; left = x/flag; right = x%10; if (left != right) return false; x = (x%flag)/10; flag = flag/100; } return true; } };
- 題目分析:第一想到的就是將他變成一個字串然後對他進行判斷是否是迴文串。但是題目不能變為字串。這裡我們就可以變換一種方法。比如對數字“12321”,12321/10000=1,首位為1, 12321%10=1,尾部為1,然後繼續判斷232這個數字,按照相同的方法(這裡的關鍵是剩餘數字的位數需要確定)
- 題目三:判斷一個字串是否是迴文,只考慮字母和數字,其他空格之類的忽略。
- 思路:這個就是簡答的判斷字串是否是迴文的情況。碰到不是字母或者是數字的情況直接跳轉到下一個字串,頭尾依次進行比較。這裡需要考慮大小寫的問題,所以比較是否相同直接利用assic的值進行比較比較合適。s[left] +32 -'a')%32 != (s[right] +32 -'a')%32 ->>這裡%32表示大小寫的assic 32是一個迴圈。
- 程式碼
class Solution { public: bool isPalindrome(string s) { int len = s.size(); int left = 0, right = len-1; while (left < right){ if (!isAlphaNum(s[left])) left++; else if (!isAlphaNum(s[right])) right--; else if((s[left] +32 -'a')%32 != (s[right] +32 -'a')%32) return false;//這裡考慮到大小寫,所以直接這樣用assic進行比較 else{ left++,right--; } } return true; } bool isAlphaNum(char &ch) { if (ch >= 'a' && ch <= 'z') return true; if (ch >= 'A' && ch <= 'Z') return true; if (ch >= '0' && ch <= '9') return true; return false; } };
- 思路:這個就是簡答的判斷字串是否是迴文的情況。碰到不是字母或者是數字的情況直接跳轉到下一個字串,頭尾依次進行比較。這裡需要考慮大小寫的問題,所以比較是否相同直接利用assic的值進行比較比較合適。s[left] +32 -'a')%32 != (s[right] +32 -'a')%32 ->>這裡%32表示大小寫的assic 32是一個迴圈。
- 題目四:
給定一個字串s,分割槽s使得分割槽的每個子字串是一個迴文。 返回s的所有可能的迴文分割槽。 例如,給定s =“aab”, 返回 [ [“aa”,“b”], [“a”,“a”,“b”] ]]
- 題目分析:實際上這道題目是一道組合的題目,對付組合的題目,回溯法是一個很好的方法。這裡是要拆分字串(拆分的串都是迴文串),得出所有的拆分情況。組合問題->回溯法,DFS演算法很好的解決了這個問題。先是針對一個一個字元進行拆分,然後是針對兩個字元是迴文串的串,之後是含有三個字元是迴文串的字元,依次類推(這裡需要一個函式是判斷該字串是否為迴文的函式,給定首尾進行判斷)。dfs遞迴的條件是找到符合要求的迴文串,然後對後面的串也進行遞迴的求解(從頭開始繼續進行遞迴求解)
- 例項分析:
a b c e e -> 第一組:a 迴文 a進temp, b迴文 b進temp, c 迴文 c進temp , e 迴文 e進temp , e 迴文 e進temp找到一組,出容器。
第二組:回溯,回溯到第一個e,進行兩個字元迴文查詢判斷,找到ee,之後就沒有了。 - 程式碼:
class Solution { public: vector<vector<string>> partition(string s) { vector<vector<string> > res; vector<string> temp; partition(s, 0, temp, res); return res; } void partition(string &s, int start, vector<string> temp, vector<vector<string> > &res){ int len = s.size(); if (start == len) res.push_back(temp); for (int i=start; i<len; i++){ if (isPalindromeStr(s, start, i)){ temp.push_back(s.substr(start, i-start+1)); partition(s, i+1, temp, res); temp.pop_back(); } } } bool isPalindromeStr(string s, int start, int end){ while (start < end){ if (s[start] != s[end]){ return false; }else start++,end--; } return true; } };
(迴文串)leetcode各種迴文串問題
相關文章
- LeetCode - 409 - 最長迴文串LeetCode
- LeetCode125. 驗證迴文串LeetCode
- LeetCode題集-5 - 最長迴文子串(一)LeetCode
- LeetCode 5.最長迴文子串LeetCode
- 最長迴文子串 -- 三種解答
- LeetCode-5. 最長迴文子串(Manacher)LeetCode
- Leetcode[字串] 5. 最長迴文子串LeetCode字串
- 迴文串問題(動態規劃DP C++)動態規劃C++
- Leetcode:1616. 分割兩個字串得到迴文串LeetCode字串
- leedcode-最長迴文串
- 省錢構建迴文串
- 1203- 最長迴文串
- java 最長迴文子串Java
- 【每日一題】125. 驗證迴文串每日一題
- Leetcode5: Longest Palindromic Substring(最長迴文子串)LeetCode
- 每日一道 LeetCode (48):最長迴文子串LeetCode
- LeetCode題集-5 - 最長迴文子串之馬拉車(二)LeetCode
- 5. 最長迴文子串
- Leetcode 344:驗證迴文串(最詳細解決方案!!!)LeetCode
- 每日一練(40):驗證迴文串
- Amazon面試題:尋找最長迴文子串面試題
- 演算法-兩最長迴文子串演算法
- 每日一算--最長迴文子串
- 常用演算法之驗證迴文串演算法
- 從0打卡leetcode之day 6--最長迴文串LeetCode
- 第五章 字串專題 ---------------- 5.10 題解:神奇的迴文串字串
- 判斷迴文串 字串/數字相互轉換字串
- [動態規劃] 六、最長迴文子串動態規劃
- 演算法之字串——最長迴文子串演算法字串
- 最長迴文子串你學會了嗎?
- 程式碼隨想錄day46 || 647 迴文子串, 516 最長迴文子序列
- 淺談最長迴文子串求法——字串雜湊字串
- SYZOJ - 補充構造迴文串(動態規劃)動態規劃
- 每天一道演算法題:最長迴文子串演算法
- 迴文數問題
- leetcode 解題 5. 最長迴文子串 python@ 官解,暴力法,動態法,manacher 法LeetCodePython
- leetcode的第9題:迴文數LeetCode
- LeetCode迴文數(Python)LeetCodePython
- 杭電OJ2029迴文串——Palindromes _easy version(C語言解析)C語言