一、问题描述
- 给定一个数组,无重复元素,返回所有的排列数
-
For example,
[1,2,3]
have the following permutations:
[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
-
递归求解排列:例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
可以这样想:固定第一个字符a,求后面两个字符bc的排列。当两个字符bc的排列求好之后,我们把第一个字符a和后面的b交换,得到bac,接着我们固定第一个字符b,求后面两个字符ac的排列。现在是把c放到第一位置的时候了。记住前面我们已经把原先的第一个字符a和后面的b做了交换,为了保证这次c仍然是和原先处在第一位置的a交换,我们在拿c和第一个字符交换之前,先要把b和a交换回来。在交换b和a之后,再拿c和处在第一位置的a进行交换,得到cba。我们再次固定第一个字符c,求后面两个字符b、a的排列。
-
递归求解组合数:假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。
这里有一个问题,如果数组长度为7,需要的组合长度为5,当开始的begin为3时,后面的递归已经没必要运行了,因为后面的元素无论如何也无法构成这个组合,因为数目不够。
- 求解排列数
public class Solution { List<List<Integer>> result=new ArrayList<List<Integer>>(); public List<List<Integer>> permute(int[] nums) { if(nums==null || nums.length==0) return result; permuteCore(nums,0); return result; } private void permuteCore(int[] nums,int i){ if(nums.length-1==i){ List<Integer> list=new ArrayList<Integer>(); for(int k=0;k<nums.length;k++){ list.add(nums[k]); } result.add(list); //result.add(new ArrayList<Integer>(Arrays.asList(nums))); return; } for(int j=i;j<nums.length;j++){ int tem=nums[i]; nums[i]=nums[j]; nums[j]=tem; permuteCore(nums,i+1); nums[j]=nums[i]; nums[i]=tem; } } }
写代码时出现一个问题,就是将int[] nums数组通过Arrays.asList(nums)函数转化为list时,报错:no suitable constructor found for ArrayList(List<int[]>),也就是说这个函数并没有按照我们预想的方式将nums中的元素转化为list<int>,而是将整个数组作为一个元素转化为list<int[]>,为什么会出现这种情况?
这是因为Arrays.asList(T...a)方法中T是参数类型,因此必须为一个Object类型,但是int不是,而int[]却是,因而出现了上面的情况。如果你打算将一个基本类型的数组转换为所对应的封装类型的list,使用Apache Commons Lang吧,可能你的项目正在使用它,类似下面这样使用ArrayUtils.toObject:
同时,该方法还有另一个问题,该方法返回的ArrayList不是java.util.ArrayList,而是Arrays的内部类,该内部类提供类了size\toArray\get\set\indexOf\contains方法,而无法修改list。List<Integer> list = Arrays.asList(ArrayUtils.toObject(new int[] { 1, 2 }));
- 求解组合数
package com.lemon.JavaSe; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Combination{ public static void main(String[] args){ char chars[]={'a','b','c'}; combination(chars); } public static void combination(char[] chars){ if(chars==null || chars.length==0) return; List<Character> list=new ArrayList<Character>(); for(int i=1;i<=chars.length;i++){ combinationCore(chars, 0,i, list); } } public static void combinationCore(char[] chars,int begin,int number,List<Character> list){ if(number==0){ System.out.println(list.toString()); return; } if(begin==chars.length || (number>chars.length-begin)) return; list.add(chars[begin]); combinationCore(chars, begin+1, number-1, list); list.remove((Character)chars[begin]); combinationCore(chars, begin+1, number, list); } }