- 套餐内商品的排列顺序 1 中等 相关标签
某店铺将用于组成套餐的商品记作字符串 goods,其中 goods[i] 表示对应商品。请返回该套餐内所含商品的 全部排列方式 。
返回结果 无顺序要求,但不能含有重复的元素。
示例 1:
输入:goods = “agew”
输出:[“aegw”,“aewg”,“agew”,“agwe”,“aweg”,“awge”,“eagw”,“eawg”,“egaw”,“egwa”,“ewag”,“ewga”,“gaew”,“gawe”,“geaw”,“gewa”,“gwae”,“gwea”,“waeg”,“wage”,“weag”,“wega”,“wgae”,“wgea”]提示:
1 <= goods.length <= 8
import java.util.ArrayList;
import java.util.List;
public class GoodsPermutations {
/**
* 生成商品字符串的所有排列组合
*
* @param goods 用于排列的字符串
* @return 字符串的所有排列组合数组
*/
public static String[] getPermutations(String goods) {
// 用于存储结果的列表
List<String> result = new ArrayList<>();
// 将字符串转换为字符数组,方便操作
char[] chars = goods.toCharArray();
// 调用递归函数进行排列组合
backtrack(chars, 0, result);
// 将 List<String> 转换为 String[]
return result.toArray(new String[0]);
}
/**
* 回溯法生成字符串的全排列
*
* @param chars 字符数组
* @param index 当前处理的字符索引
* @param result 用于存储排列结果的列表
*/
private static void backtrack(char[] chars, int index, List<String> result) {
// 递归终止条件:当前索引到达字符数组的末尾
if (index == chars.length) {
// 将当前排列转换为字符串并加入结果列表
result.add(new String(chars));
return;
}
// 使用一个布尔数组避免重复字符交换
boolean[] used = new boolean[256]; // 假设字符集为 ASCII,共有 256 个字符
// 遍历从当前索引开始的所有字符
for (int i = index; i < chars.length; i++) {
// 如果当前字符已经处理过(避免重复),跳过
if (used[chars[i]]) {
continue;
}
// 标记当前字符为已使用
used[chars[i]] = true;
// 交换当前字符和索引位置的字符
swap(chars, index, i);
// 递归处理下一个索引
backtrack(chars, index + 1, result);
// 回溯:撤销交换
swap(chars, index, i);
}
}
/**
* 交换字符数组中两个索引位置的字符
*
* @param chars 字符数组
* @param i 第一个索引
* @param j 第二个索引
*/
private static void swap(char[] chars, int i, int j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
}
/**
* 主方法:测试用例
*/
public static void main(String[] args) {
String goods = "agew";
String[] permutations = getPermutations(goods);
for (String permutation : permutations) {
System.out.println(permutation);
}
}