Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s = "aab",
Return
[
["aa","b"],
["a","a","b"]
]
最原始的思路,典型的DFS,終止條件+判斷條件,其中判斷條件是子字符串是不是palindrome。
一個改進版的思路,取代判斷條件需要每次判斷子字符串是否是palindrome, 轉化成爲一個DP的問題,用一個table來保存結果,因爲在上面的原始思路中,有很多字符串需要被重複計算。
下面着重解釋一下這個table:
table[ i ] [ j ] 的值代表字符串中從下標 i 到下標 j 的子串是否是 palindrome。 那麼這個值可以由左下角的值推演而來,左下角的值是 table[ i+1 ][ j-1 ]。
很容易可以想到,如果 [ i+1 ][ j-1 ] 不是一個palindrome 那麼 [ i ][ j ] 一定也不是。
很容易可以想到,如果 [ i+1 ][ j-1 ] 是一個palindrome 那麼 [ i ][ j ] 相當於在這個子串上的左邊附加了sring[ i ], 在右邊附加上string[ j ], 那麼新的子串是否相等就取決於這兩個char是否相等。
推演的方法確定了,就要確定base case:
對角線上的值是奇數子串的base case, 一定是true。
對角線元素上(或右)的值是偶數子串的base case,取決於相鄰兩個字符是否相等。
思路是先用字符串構建好table, 然後每次判斷子串是否是palindrome的時候直接去table裏面查就可以了。
代碼如下
public class Solution { boolean[][] table; public ArrayList<ArrayList<String>> partition(String s) { ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>(); table = buildTable(s); partition(s,0 ,new ArrayList<String>(),result); return result; } public void partition(String s,int from, ArrayList<String> re,ArrayList<ArrayList<String>> result) { if(from == s.length()){ result.add(new ArrayList<String>(re)); return; } for(int i=1; i<=s.length()-from; i++){ String part = s.substring(from,from+i); // if(isPalindrome(part)){ if(table[from][from+i-1]){ re.add(part); partition(s,from+i,re,result); re.remove(re.size()-1); } } } public boolean isPalindrome(String s){ int i=0; int j=s.length()-1; while(i<j){ if(s.charAt(i++)!=s.charAt(j--)){ return false; } } return true; } public boolean[][] buildTable(String s){ int length = s.length(); boolean[][] result = new boolean[length][length]; for(int i=0;i<length;i++){ result[i][i] = true; if(i>0){ result[i-1][i] = s.charAt(i)==s.charAt(i-1); } } for(int i=0;i<length;i++){ int k=i-1; int m=i+1; while(k>=0&&m<length){ result[k][m] = result[k+1][m-1]&&s.charAt(k)==s.charAt(m); k--; m++; } if(i>0){ k = i-2; m = i+1; while(k>=0&&m<length){ result[k][m] = result[k+1][m-1]&&s.charAt(k)==s.charAt(m); k--; m++; } } } return result; } }