原题:
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"] ]
» Solve this problem
方法:
DFS算法,for-loop的步骤为:从左往右遍历string并取其substring,如果当前的substring是一个回文,保存,递归;如果不是,继续循环,取下一个字符加入到substring,直到substring的长度等于原来string的长度。
代码:
public class Solution {
public ArrayList<ArrayList<String>> partition(String s) {
// Start typing your Java solution below
// DO NOT write main() function
ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
ArrayList<String> tmp = new ArrayList<String>();
partitionImp(res, tmp, s);
return res;
}
private void partitionImp(ArrayList<ArrayList<String>> res, ArrayList<String> tmp, String s){
if(s.length() == 0){
res.add(new ArrayList<String>(tmp));
return;
}
for(int i=0; i<s.length(); i++){
String sub = s.substring(0, i+1);
if(isPartition(sub)){
tmp.add(sub);
partitionImp(res, tmp, s.substring(i+1));
tmp.remove(tmp.size()-1);
}
}
}
private boolean isPartition(String str){
int i=0, j=str.length()-1;
while(i < j)
if(str.charAt(i++) != str.charAt(j--))
return false;
return true;
}
}
方法2:
这道题的另一个方法便是DP,用二维布尔矩阵记录对应相等的回文位置。这个二维的布尔矩阵富含了很多内容,虽然只有一半被赋值,但是从中可以知道奇数情况、偶数情况的每个节点的回文对应起始位置。
有了这个矩阵,剩下的便是和方法一一样的DFS算法了,这个矩阵提供的好处就是一次性的用O(N^2)
方法2代码:
public class Solution {
public ArrayList<ArrayList<String>> partition(String s) {
ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
ArrayList<String> tmp = new ArrayList<String>();
dfs(res,tmp,s,table(s),0);
return res;
}
public void dfs(ArrayList<ArrayList<String>> res, ArrayList<String> tmp, String s, boolean[][] T, int pos){
if (pos==s.length()) res.add(new ArrayList<String>(tmp));
for(int i=pos;i<s.length();i++){
if(T[pos][i]){
tmp.add(s.substring(pos,i+1));
dfs(res,tmp,s,T,i+1);
tmp.remove(tmp.size()-1);
}
}
}
public boolean[][] table(String s){
boolean[][] T = new boolean[s.length()][s.length()];
for(int i=0;i<s.length();i++){
T[i][i] = true;
}
for(int i=0;i<s.length();i++){
//even
int l = i - 1;
int r = i;
while(l>=0 && r<s.length() && s.charAt(l)==s.charAt(r))
T[l--][r++] = true;
//odd
l = i -1;
r = i + 1;
while(l>=0 && r<s.length() && s.charAt(l)==s.charAt(r))
T[l--][r++] = true;
}
return T;
}
}
小结:
在DFS的for-loop中加入if判断,标准的DFS。关于这类求全部序列题,基本要领就是多练习,多尝试。
关于方法二,矩阵的理解是关键,这个矩阵,在Longest Palindromic Number中会再次以另一种方式构建,可以提供参考。