问题I:
给定一个字符串,找出这个字符串的所有子串,从左往右找。例:abc,所有子串:a,b,c,ab,ac,bc,abc,“”。
递归拆解思路:
1.如果要a,会有结果a,ab,abc,ac;如果不要a,会有结果b,c,bc
2.如果要a,要b会有结果ab,abc;如果要a不要b会有结果a,ac
以此类推......
综上所述
当遍历字符串到任一位置n时,可进行“要”或者“不要”的操作(n-1同样是已处理完)
代码:
import java.util.ArrayList;
import java.util.List;
/**
* 获取字符串所有的子序列
*/
public class Subsequence {
public static void main(String[] args) {
String target = "abc";
findSub(target);
}
private static void findSub(String target) {
if (target == null || target.length() < 1) {
return;
}
char[] arr = target.toCharArray();
List<String> subList = new ArrayList<>();
String tmp = "";
sub(arr, 0, subList, tmp);
for (int i=0; i<subList.size(); i++) {
System.out.println(subList.get(i));
}
}
/**
* 第n个位置要或不要的决策
* @param chars 给定的字符串(不变)
* @param index 遍历至字符串某一位置
* @param subList 子串集
* @param tmp n-1的字符串结果
*/
private static void sub(char[] chars, int index, List<String> subList, String tmp) {
if (chars == null || chars.length < 1) {
return;
}
if (index == chars.length) {
subList.add(tmp);
return;
}
//不要index位置的字母
sub(chars, index + 1, subList, tmp);
//要index位置的字母
tmp = String.format("%s%s", tmp, chars[index]);
sub(chars, index + 1, subList, tmp);
}
}
问题II:
打印一个字符串的全部排列
思路:
1.剩余n个字符,遍历剩余n个字符,任一字母可以添加到当前的字符序列中组合成结果
2.将使用的字母移除剩余字符集合;重复步骤1
代码:
public class SubsequenceSort {
public static void main(String[] args) {
String target = "abc";
char[] chars = target.toCharArray();
List<Character> last = new ArrayList<>();
for (char c : chars) {
last.add(c);
}
List<String> result = new ArrayList<>();
spell(last, "", result);
for (String str : result) {
System.out.println(str);
}
}
private static void spell(List<Character> last, String tmp, List<String> result) {
if (last == null || last.size() < 1) {
result.add(tmp);
return;
}
String spellStr;
Character c;
for (int i=0; i<last.size(); i++) {
c = last.get(i);
spellStr = String.format("%s%s", tmp, c);
last.remove(i);
spell(last, spellStr, result);
//恢复现场
last.add(i, c);
}
}
}