【LeetCode】 【dp】 迴文系列
以下幾題:
Leetcode 9. Palindrome Number
給定一個數字,判斷數字是否為迴文數字。
Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.
Example 1:
Input: 121 Output: true
Example 2:
Input: -121 Output: false Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Example 3:
Input: 10 Output: false Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
1,判斷迴文只需要使用兩個指標一前一後比較數字即可。
bool isPalindrome(int x) { if(x<0 || &x==nullptr) return false; string x_str = to_string(x); int lo = 0; int hi = x_str.size()-1; while(lo<=hi) { if (x_str[lo] != x_str[hi]) return false; lo++; hi--; } return true; }
這種方法需要先將int轉成string,最終得分在45%左右。
2,如何不用換成字串直接判斷呢?
按照最直接的方法,迴文數的定義就是數字從正序或反序來讀都是一樣的,那就將數字顛倒過來後再判斷是否一樣。
因此可以從個位數開始依次讀,再不斷進位相加,得到顛倒的數字。
首先儲存一個輸入x的備份source_x,然後對x的每一位迴圈,reverse_x = reverse_x*10 + x%10 的方式不斷得到高位的數字。如1221可得到 reverse_x = 0*10 + 1221%10 = 1,x = x/10 = 1221/10 = 122。
bool isPalindrome(int x) { if(x<0 || &x==nullptr) return false; int source_x = x; int reverse_x = 0; while(x) { reverse_x = reverse_x*10 + x%10; x = x/10; } if (source_x == reverse_x) return true; return false; }
LeetCode 5. Longest Palindromic Substring
最長迴文子串。使用DP來做。
定義dp[i][j]表示從i到j的字串是否為迴文串
初始化:每個單獨的字母都是迴文串:dp[i][i] = true
遞推:判斷 dp[i][j] 時,若 dp[i+1][j-1] == true 且 s[i] == s[j] ,即對於abcba,bcb是迴文串且 'a' == 'a',因此 abcba 也是迴文串。
注意幾個地方:
1,可以看到遞推時,i 由 i+1 的狀態推得,因此在迴圈時,i 應該從大往小遞推;
2,對於兩個字元的,如 'bb',中間字串為空,因此初始化時不僅要初始化每個單個的字元 dp[i][i],也要初始化連續的兩個字元 dp[i][i+1]
string longestPalindrome(string s) {
/*
最長連續迴文串
使用dp,dp[i][j]表示i起點j終點的迴文串長度
*/
if (s.length() <= 1)
return s;
int n = s.length();
// 首先初始化
bool dp[n][n] = {false};
// 所有單個字母都是迴文的
for (int i=0; i<n; i++) {
dp[i][i] = true;
// 兩個相鄰字母相等則也時迴文的
if (i<n-1)
dp[i][i+1] = s[i]==s[i+1];
}
// 遍歷每種可能
// i應從大到小遍歷
for (int i=n-3; i>=0; i--) {
for(int j=i+2; j<n; j++) {
dp[i][j] = s[i]==s[j] && dp[i+1][j-1]; // 若i與j處字元相同 且 [i+1][j-1]是迴文
}
}
int longest_length = 0;
string longest_str = "";
for (int i=0; i<n; i++) {
for(int j=i; j<n; j++) {
if (dp[i][j]==true && j-i+1>longest_length) { // 當前是迴文串時 且 是目前的最長的迴文串
longest_str = s.substr(i,j-i+1);
longest_length = j-i+1;
}
}
}
return longest_str;
}