遇到这个题目,我真的是头大。还是硬着头皮往下看,嗯,典型的回溯法。就写吧,回溯法我也讲不明白说实话,只是做了几道题然后慢慢找到了规律就会了。先上代码(代码花费的时间好多啊!!):
public List<List<String>> partition(String s) {
List<List<String>> result = new ArrayList<>();
if (s.length() == 0)
return result;
List<String> list = new ArrayList<>();
helper(result, list, s, 0);
return result;
}
//回溯法求解
private void helper(List<List<String>> result, List<String> parent, String s, int startIndex) {
if (startIndex == s.length()) { //如果到最后,则把上一层传下来的数组直接返回
result.add(parent);
return;
}
for (int i = startIndex; i < s.length(); ++i) {
List<String> cur = new ArrayList<>(parent);
//找到一个回文子串,加入到当前层的数组中,传递到下一层,并遍历此子串后面的串
if (is_pa(s.substring(startIndex,i+1))) {
cur.add(s.substring(startIndex, i+1));
//这里的i+1相当于要从子串后面开始遍历,且把cur传到了下一层
helper(result, cur, s, i+1);
} else
continue;
}
}
//判断一个子串是不是回文的
private boolean is_pa(String s) {
int i = 0, j = s.length()-1;
for (; i < j && s.charAt(i) == s.charAt(j); ++i, --j);
return i >= j;
}
然后我看了一个解答,盗了一个图,就是这样的:
我看次解答的另一种解法就是在回溯的过程中加入了动态规划,其实就是使用了一个二维数组dp[i][j]
,然后dp[i][j]
的值就是s.subString(i,j)
是不是一个回文字符串,那样在回溯的时候判断回字符串的时间复杂度就完成了O(1)。具体的动态规划过程可以看leetcode_5:Longest Palindromic Substring。