[LeetCode] Palindrome Partitioning 拆分回文串
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
Example:
Input: "aab"
Output:
[
["aa","b"],
["a","a","b"]
]
这又是一道需要用DFS来解的题目,既然题目要求找到所有可能拆分成回文数的情况,那么肯定是所有的情况都要遍历到,对于每一个子字符串都要分别判断一次是不是回文数,那么肯定有一个判断回文数的子函数,还需要一个DFS函数用来递归,再加上原本的这个函数,总共需要三个函数来求解。我们将已经检测好的回文子串放到字符串数组out中,当s遍历完了之后,将out加入结果res中。那么在递归函数中我们必须要知道当前遍历到的位置,用变量start来表示,所以在递归函数中,如果start等于字符串s的长度,说明已经遍历完成,将out加入结果res中,并返回。否则就从start处开始遍历,由于不知道该如何切割,所以我们要遍历所有的切割情况,即一个字符,两个字符,三个字符,等等。。首先判断取出的子串是否是回文串,调用一个判定回文串的子函数即可,这个子函数传入了子串的起始和终止的范围,若子串是回文串,那么我们将其加入out,并且调用递归函数,此时start传入 i+1,之后还要恢复out的状态。
那么,对原字符串的所有子字符串的访问顺序是什么呢,如果原字符串是 abcd, 那么访问顺序为: a -> b -> c -> d -> cd -> bc -> bcd-> ab -> abc -> abcd, 这是对于没有两个或两个以上子回文串的情况。那么假如原字符串是 aabc,那么访问顺序为:a -> a -> b -> c -> bc -> ab -> abc -> aa -> b -> c -> bc -> aab -> aabc,中间当检测到aa时候,发现是回文串,那么对于剩下的bc当做一个新串来检测,于是有 b -> c -> bc,这样扫描了所有情况,即可得出最终答案,代码如下:
主要看递归的for循环,第一层for是指我String回文第一个有几个字符 1, 2 ,3 ,4 ,5 都有可能
取完第一个回文后,剩下的字串取回文还有 1 , 2, 3 ,4 5, 等可能,接着来 一层一层的取回文,直到把String分割完了,就加到List里面,这里if用的细节,报这个了我们每次分割的都是回文,不是的话就没必要浪费这个实干;
class Solution {
public List<List<String>> partition(String s) {
List<List<String>> partitions = new ArrayList<>();
List<String> tempPartition = new ArrayList<>();
doPartition(s, partitions, tempPartition);
return partitions;
}
private void doPartition(String s, List<List<String>> partitions,
List<String> tempPartition) {
if (s.length() == 0) {
partitions.add(new ArrayList<>(tempPartition));
return;
}
for (int i = 0; i < s.length(); i++) {
if (isPalindrome(s, 0, i)) {
//取到的是0-i的String
tempPartition.add(s.substring(0, i + 1));
doPartition(s.substring(i + 1), partitions, tempPartition);
tempPartition.remove(tempPartition.size() - 1);
}
}
}
private boolean isPalindrome(String s, int begin, int end) {
while (begin < end) {
if (s.charAt(begin++) != s.charAt(end--)) {
return false;
}
}
return true;
}
}
class Solution {
public List<List<String>> partition(String s) {
List<String> list = new ArrayList<>();
List<List<String>> result = new ArrayList<>();
help(list, result, s);
return result;
}
private void help(List<String> list, List<List<String>> result, String s){
if(s.length() == 0){
result.add(new ArrayList<>(list));
return;
}
for(int i = 0; i < s.length(); i++){
if(panduan(s, 0, i)){
list.add(s.substring(0,i+1));
help(list, result, s.substring(i+1));
list.remove(list.size() - 1);
}
}
}
private boolean panduan(String s, int start, int end){
while(start < end){
if(s.charAt(start++) != s.charAt(end--))
return false;
}
return true;
}
}
错误的答案 只是有这个想法 等Stringbuilder会用了再回来搞搞
class Solution {
public List<List<String>> partition(String s) {
List<List<String>> partitions = new ArrayList<>();
List<String> partitionList = new ArrayList<>();
StringBuilder sb = new StringBuilder;
for(int i=1; i <= s.length(); i++)
help();
return partitions;
}
private void help(List<List<String>> partitions, List<String> partitionList,
int size, StringBuilder sb){
if(sb.length == size){
if(isPalindrome(sb.toString, 0, sb.length - 1))
partitions.add(new ArrayList<>(partitionList));
return;
}
for(int i = start; i < s.length; i++){
sb.append(s.charAt(i));
help(partitions, partitionList, size, sb);
patitionList.remove(partitionList.size() - 1);
}
}
private boolean isPalindrome(String s, int start, int end){
while(start < end){
if(s.charAt(start++) != end.charAt(end--))
return false;
}
return true;
}
}