我们在笔试中经常会遇到需要对字符串进行排列或者组合的题目。本篇文章对字符串的排列和组合进行递归版本的实现。
1. 字符串的组合
例子:输入:abc,它的组合有:a、b、c、ab、ac、bc、abc
代码实现:
package com.offer.manongqiuzhi.String;
/**
* @author pcwl
* @description:递归实现字符串的组合
*/
public class CombinationString {
public static void printAllSubString(String str){
if(str == null){
return;
}
char[] chars = str.toCharArray();
if(chars.length > 0){
String pre = new String(""); // pre:用于表示从0到i-1位置上形成的结果
printAllSubString(0, pre, chars);
}else{
System.out.println(""); // 输入空字符串也会打印空
}
}
public static void printAllSubString(int i, String pre, char[] chars){
// 迭代终止条件
if(i == chars.length){
// 说明已经到最后一个字符了,所有的选择都已经做完了,应该返回了
System.out.println(pre);
return;
}
// 如果没有到最后一个字符,那么当前字符有两种选择:选择要 和 选择不要
printAllSubString(i + 1, pre, chars); // 不要当前字符
printAllSubString(i + 1, pre + String.valueOf(chars[i]), chars); // 要当前字符
}
// 测试
public static void main(String[] args) {
printAllSubString("abc");
}
}
运行结果:
2. 字符串的排列
01
全排列
举例:输入字符串 abc,则输出由字符 a、b、c 所能排列出来的所有字符串 abc、acb、bac、bca、cab 和 cba。
-
代码实现:
package com.offer.manongqiuzhi.String;
/**
* @author pcwl
* @description:递归实现全排列
*/
public class PermutationString {
public static void printAllSort(String string){
if(string == null){
return;
}
char[] chars = string.toCharArray();
if(chars.length > 0){
printAllSort(0, chars);
}
}
// 对i及i以后的字符进行全排列
public static void printAllSort(int i, char[] chars){
// 递归终止条件
if(i == chars.length){
System.out.println(String.valueOf(chars));
}
for(int j = i; j < chars.length; j++){
swap(i, j, chars); // 第 i 个位置有 i ~ (n - 1) 种选择。n 为字符串的长度
printAllSort(i + 1, chars);
swap(i, j, chars); // 保证 i 后面的字符每次都是和 i 位置上的元素进行的交换,还需要将 i 和 j 交换回来
}
}
public static void swap(int i, int j, char[] chars){
int temp = chars[i];
chars[i] = chars[j];
chars[j] = chars[i];
}
public static void main(String[] args) {
printAllSort("abcc");
}
}
02
去重全排列
package com.offer.manongqiuzhi.String;
import java.util.HashSet;
/**
* @author pcwl
* @description:递归实现全排列(去重)
*/
public class StringByRemoveDuplicate {
public static void printAllSort(String string){
if(string == null){
return;
}
char[] chars = string.toCharArray();
if(chars.length > 0){
printAllSort(0, chars);
}
}
// 对i及i以后的字符进行全排列
public static void printAllSort(int i, char[] chars){
// 递归终止条件
if(i == chars.length){
System.out.println(String.valueOf(chars));
}
// 用于保证每次交换的字符不存在重复的字符
HashSet<Character> set = new HashSet<>();
for(int j = i; j < chars.length; j++){
if(!set.contains(chars[j])){
set.add(chars[j]);
// 第 i 个位置有 i ~ (n - 1) 种选择。n 为字符串的长度
swap(i, j, chars);
printAllSort(i + 1, chars);
// 保证 i 后面的字符每次都是和 i 位置上的元素进行的交换,还需要将 i 和 j 交换回来
swap(i, j, chars);
}
}
}
public static void swap(int i, int j, char[] chars){
int temp = chars[i];
chars[i] = chars[j];
chars[j] = chars[i];
}
public static void main(String[] args) {
printAllSort("abcc");
}
}
-------- END ---------
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。关注公众号并回复 888 领取,更多内容陆续奉上