输入一个字符串,输出该字符串中相邻字符的所有组合。
举个例子,如果输入abc,它的组合有a、b、c、ab、bc、abc。(注意:输出的组合需要去重)(40分)
输入描述:
一个字符串
输出描述:
一行,每个组合以空格分隔,相同长度的组合需要以字典序排序,且去重。
示例1
输入
bac
输出
a b c ac ba bac
解题思路1:
类似Lintcode 17. 子集,不过需要注意这里不能先对字符串进行排序然后使用Lintcode 18. 子集 II的方法来去重,因为本题需要保证字符之间的顺序性,所以采用检查res中是否包含当前sb,若包含则return。
对于相邻字符的判断,也通过字符串函数contains,因为只有相邻字符组成的字符串才能在原串中找到结果。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str = sc.next();
List<String> res = new ArrayList<>();
dfs(str, res, new StringBuilder(), 0);
//先按照长度升序排序,然后再按照字典序升序排序
Collections.sort(res, new Comparator<String>(){
public int compare(String s1, String s2){
if(s1.length() != s2.length())
return s1.length() - s2.length();
else
return s1.compareTo(s2);
}
});
for(int i=0; i<res.size(); i++)
System.out.print(res.get(i) + " ");
}
private static void dfs(String str, List<String> res, StringBuilder sb, int index){
//去重
if (res.contains(sb.toString()))
return;
//保证是相邻字符
if (sb.length() > 0 && str.contains(sb.toString()))
res.add(sb.toString());
for(int i=index; i<str.length(); i++){
sb.append(str.charAt(i));
dfs(str, res, sb, i+1);
sb.deleteCharAt(sb.length()-1);
}
}
}
解题思路2:
思路1对于本题太复杂了,由于有相邻的特性,所以可以直接遍历生成不同长度的子串,使用treeSet来进行排序
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str = sc.next();
//i代表遍历的字符长度,j代表起始位置,使得生成不同的substring(j, j+1)
for (int i = 1; i <= str.length(); i++) {
TreeSet<String> treeSet = new TreeSet<>();
for (int j = 0; j + i <= str.length(); j++)
treeSet.add(str.substring(j, j + i));
for (String s : treeSet)
System.out.print(s + " ");
}
}
}