排列子集总结
子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[ [3], [1], [2],[1,2,3],[1,3], [2,3], [1,2], [] ]
public static List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
backtrack(0, nums, res, new ArrayList<Integer>());
return res;
}
private static void backtrack(int i, int[] nums, List<List<Integer>> res, ArrayList<Integer> tmp) {
res.add(new ArrayList<>(tmp));
for (int j = i; j < nums.length; j++) {
tmp.add(nums[j]);
backtrack(j + 1, nums, res, tmp);
tmp.remove(tmp.size() - 1);
}
}
子集 II
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[[2],[1],[1,2,2],[2,2],[1,2],[]]
public class Test55 {
List<List<Integer>> returnList = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
if(nums == null){
return returnList;
}
Arrays.sort(nums);
//排序
List<Integer> lists = new ArrayList<>();
helper(nums,lists,0);
return returnList;
}
public void helper(int[] nums,List<Integer> lists,int start){
returnList.add(new ArrayList<>(lists));
for(int i =start;i<nums.length;i++){
if(i>start && nums[i]==nums[i-1]){
continue;
}
lists.add(nums[i]);
helper(nums,lists,i+1);
lists.remove(lists.size()-1);
}
}
}
全排列
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[[1,2,3], [1,3,2],[2,1,3], [2,3,1], [3,1,2],[3,2,1]]
static List<List<Integer>> list = new ArrayList<>();
public static List<List<Integer>> permute(int[] nums) {
if (nums == null || nums.length == 0) {
return list;
}
List<Integer> list1 = new ArrayList<>();
dpf(nums,list1);
return list;
}
public static void dpf(int[] nums,List<Integer> list1){
if(list1.size() ==nums.length){
list.add(new ArrayList<>(list1));
}else {
for(int i =0;i<nums.length;i++){
//如果已经在数组里面了
if(list1.contains(nums[i])){
continue;
}
list1.add(nums[i]);
dpf(nums,list1);
list1.remove(list1.size()-1);
}
}
}
全排列II
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[[1,1,2], [1,2,1],[2,1,1]]
public static List<List<Integer>> permuteUnique(int[] nums) {
if (nums == null || nums.length == 0) {
return lists;
}
//一定要排序
Arrays.sort(nums);
List<Integer> list = new ArrayList<>();
boolean[] visitlist = new boolean [nums.length];
dfs(nums,list,visitlist);
return lists;
}
private static void dfs(int[] nums,List<Integer> list,boolean[] visitlist){
if(list.size() ==nums.length){
lists.add(new ArrayList<>(list));
return;
}else {
for(int i =0;i<nums.length;i++){
if(visitlist[i]){
continue;
}
if(i > 0 && nums[i] == nums[i-1] && visitlist[i-1] ==false)
{
continue;
}
list.add(nums[i]);
visitlist[i] = true;
dfs(nums,list,visitlist);
list.remove(list.size()-1);
visitlist[i] = false;
}
}
}
字符串排列
题目
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
public class Test5 {
public static void main(String[] args) {
List<String> strings = Permutation("abc");
for(String str : strings){
System.out.println(str);
}
}
static ArrayList<String> returnList = new ArrayList<>();
public static List<String> Permutation(String str) {
if(str=="" || str.length() ==0){
return returnList;
}
helper(str.toCharArray(),0);
Collections.sort(returnList);
return returnList;
}
public static void helper(char[] chars, int index) {
if(index == chars.length-1){
String val = String.valueOf(chars);
if (!returnList.contains(val)) {
//如果最后list没有这个string,因为可能交换后有重复的
returnList.add(val);
}
return;
}
for(int i =index;i<chars.length;i++){
swap(chars, index, i);
helper(chars,index+1);
swap(chars, index, i);
}
}
public static void swap(char[] chars,int i, int j) {//交换数组中的两个位置中的值
char temp =chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
}