LeetCode-46. Permutations +组合实现

一、问题描述

  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);
    	}
    }







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值