LeetCode-46. Permutations +组合实现

来源:互联网 发布:手机网络枪战游戏排行 编辑:程序博客网 时间:2024/06/08 02:45

一、问题描述

  1. 给定一个数组,无重复元素,返回所有的排列数
  2. 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]]
二、解题思路(参考自http://shukuiyan.iteye.com/blog/1095637)

  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的排列。


  2. 递归求解组合数:假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。
    这里有一个问题,如果数组长度为7,需要的组合长度为5,当开始的begin为3时,后面的递归已经没必要运行了,因为后面的元素无论如何也无法构成这个组合,因为数目不够。

三、代码

  1. 求解排列数
    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:
    List<Integer> list = Arrays.asList(ArrayUtils.toObject(new int[] { 1, 2 }));
    同时,该方法还有另一个问题,该方法返回的ArrayList不是java.util.ArrayList,而是Arrays的内部类,该内部类提供类了size\toArray\get\set\indexOf\contains方法,而无法修改list。
  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);}}







原创粉丝点击