整数全排列问题

来源:互联网 发布:修改软件下载 编辑:程序博客网 时间:2024/06/16 11:08

原文:整数全排列

题目:
n种不同面值的硬币存放在数组A中,现在需要找零钱给用户,找零金额为m,求最少硬币数找零方式
输入、输出描述
输入:
A为不同面值硬币构成的非负整数数组,n=length(A),m为待找零钱的总金额数
输出:
最少硬币数找零方式,按面值金额从小到大排序,若无解:返回长度为1的数组,且素组的元素为-1
Example
输入:
A:1,3,5n:3m:19
输出:
1,3,5,5,5


解题思路:

使用递归算法。

设一组整数为digit = {d1, d2, d3, ...., dn},记该数的全排列为A(digit),由于每一种排列的第一位数有n种情况,A(digit)就等于sum( A(digit-{di}) ),其中di属于{d1, d2, d3, ...., dn},digit-{di}表示digit数组去掉元素di之后的数组,依次类推下去。以digit={1,2,3}为例进行说明:

{1,2,3}的全排列可以分为3个子数组的全排列:

  • 1+{2,3}的全排列:123   132
  • 2+{1,3}的全排列:213   231
  • 3+{1,2}的全排列:312   321

为了避免重复的排列结果,可以用HashSet保存每次排列的结果,最后将所有结果按照数值大小进行排序。

代码:
    import java.util.*;         public class Main {      //交换数组里的两个元素      public void swap(int i,int j,int[] digit){        if(i!=j){          int temp;          temp = digit[i];          digit[i] = digit[j];          digit[j] = temp;        }      }            //将整数数组转换成数字      public int arrayToNum(int[] digit) {        int num = 0;        int xishu = 1;        for (int i = digit.length-1; i >=0; i--) {          num += digit[i]*xishu;          xishu *= 10;        }        return num;      }            //为了避免元素重复,将每次的排列结果插入一个HashSet里      Set<Integer> temp = new HashSet<>();      public void numArrange(int[] digit,int i){        if(i == (digit.length-1)){          temp.add(arrayToNum(digit));//将排列结果插入HashSet        }else{          int j;          for(j=i;j<digit.length;j++){            swap(i,j,digit);            numArrange(digit,i+1);            swap(i,j,digit);          }        }      }      public int[] solution(int[] digit,int n) {        numArrange(digit, 0);        int length = temp.size();        int[] result = new int[length];        int index = 0;         for (int i : temp) {           result[index++] = i;         }        Arrays.sort(result);//排序        return result;      }    }




原创粉丝点击