输入字符串,找出字符串中的自己的排列组合的算法
例如:s =”aab”,
那么字符串中所有的回文字符串集合:
[
[“aa”,”b”],
[“a”,”a”,”b”]
]
类似的可以延展到很多种情况 ,字符串有多少种排列可能(具体的处理有不同),大致的过程基本都是类似的。回溯法的思想来解决,在算法上会简单点。
import java.util.ArrayList;
public class PalindromePartitioning {
public static void main(String[] args) {
String s="aab";
partition(s);
}
public static ArrayList<ArrayList<String>> partition(String s) {
ArrayList<ArrayList<String>>lists=new ArrayList<ArrayList<String>>();
ArrayList<String>list=new ArrayList<String>();
partitionHelper(lists,list,s);
return lists;
}
public static void partitionHelper(ArrayList<ArrayList<String>> lists, ArrayList<String> list, String s) {
if (null == s || s.length() == 0) {
System.out.println("=== *******lists.add");
lists.add(new ArrayList<>(list));
return;
}
int len = s.length();
System.out.println("len["+"###]"+len);
for (int i = 1; i <= len;i++) {
String subStr = s.substring(0, i);
System.out.println(subStr+"===isPalindrome"+"###"+i);
if (isPalindrome(subStr)) {
System.out.println("=== list.add");
list.add(subStr);
System.out.println("===isPalindrome"+"true ###"+i);
partitionHelper(lists, list, s.substring(i, len));
System.out.println("=== list.remove"+(list.size() - 1));
list.remove(list.size() - 1);
}
}
}
public static boolean isPalindrome(String s){
if(s==null||s.length()==0) return false;
int len=s.length()/2;
for(int i=0;i<len;i++){
if(s.charAt(i)!=s.charAt(s.length()-i-1))
return false;
}
return true;
}
}
当s=”aab”以下是打印结果,回溯的过程,先拿到a,得到一组结果,回溯回去,开始aa,得到一组结果,回溯回去,然后aab
len[###]**3**
a===isPalindrome###1(*第一次函数调用*:第一下拿到a)
=== list.add(a加入)
===isPalindrome true ###1
len[###]2(拿出去a后函数执行s="ab";*第二次函数调用*:第一下拿到a)
a===isPalindrome###1
=== list.add(a加入)
===isPalindrome true ###1
len[###]1(拿出去b后函数执行s="b";*第三次函数调用*:第一下拿到b))
b===isPalindrome###1
=== list.add(b加入)
===isPalindrome true ###1
=== *******lists.add(a,a,b一组)
=== list.remove2(移除b,移除了*第三次函数调用*添加进来的b,第三次函数执行完就空了,所以*第三次函数结束*)
=== list.remove1(移除a,移除了第二次函数调用添加进来的a,*第二次函数调用*过程中的i=1执行完毕)
ab===isPalindrome###2(第三次只有b已经结束,第二次的a已经添加,现在执行到*第二次的函数*吊桶的i=2的时候)
=== list.remove0(ab不是回文所以要把原来*第一次函数*压进去的a拿走,*第二次的函数调用*结束)
aa===isPalindrome###**2**(执行函数第一次调用,i=2的情况了)
=== list.add(aa进入)
===isPalindrometrue ###2
len[###]1(*第四次函数*调用剩下的s="b")
b===isPalindrome###1
=== list.add(b加入,当前list里面有a,a,b)
===isPalindrometrue ###1
=== *******lists.add
=== list.remove1(第四次函数只有b,执行完毕结束)
=== list.remove0(第一次函数调用i=2,执行完毕结束)
aab===isPalindrome###**3**(第一次函数调用执行i=3,不是回文直接结束)