整数全排列问题

原文:整数全排列

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




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值