求数组中和为给定数的所有组合的个数

  • Post author:
  • Post category:其他




一、问题描述


给定一个数t,以及n个整数,在这n个数中找到加和为t的所有组合,例如t=4,n=6这6个数为[4,3,2,2,1,1],这样输出就有4个不同的组合它们的加和为4:4,3+1,2+2,and 2+1+1。请设计一个高效算法实现这个需求。



二、解题思路


先将数据按从小到大进行排序,然后使用回溯法遍历所有可能。注意去掉重复的结果。



三、Java代码实现

//--------------------- Change Logs----------------------
// <p>@author weiwei.han Initial Created at 2015-9-25<p>
//-------------------------------------------------------

/**
 *求任意一个数组中所有和为给定数的组合个数
 */
public class CombinationCount {

    private static int count = 0;
    private static int []array = {0, 9, 8, 3, 4, 1, 2, 7, 5, 6};
    private static int sum = 8;
    
    static int getCount() {
        CombinationCount.quickSort(array, 0, array.length-1);
        CombinationCount.sum(array.length-1);
        return count;
    }
    
    private  static int[] sum(int n) {
        if(n == 0){
            return new int[]{array[0]};
        }
        
        int length = (int)Math.pow(2, (n+1))-1;
        int a[] = new int[length];
        int b[] = sum(n-1);
        
        int i=0;
        for(i=0; i<(length-1)/2; i++) {
            a[i] = b[i];
            int temp = b[i] + array[n];
            if(temp == sum){
                count++;
            }
            a[i+(length+1)/2] = temp;
        }
        if(array[n] == sum) {
            count++;
        }
        a[(length-1)/2] = array[n];
        
        return a;
    }
    
    private static void quickSort(int []array, int left, int right) {
        if(left >= right) {
            return;
        }
        int q = pagenation(array, left, right);
        quickSort(array, left, q-1);
        quickSort(array, q+1, right);
    }
    
    private static int pagenation(int []array, int left, int right) {
        int i=left, j=right+1;
        int p = (int)Math.random()*(right-left+1)+left;
        swap(array,left, p);
        int x = array[left];
        
        while(true) {
            while(i<right && array[++i] < x);
            while(j>left && array[--j] > x);
            if(i > j) {
                break;
            }
            swap(array,i,j);
        }
        return j;
    }
    
    private static void swap(int [] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    
    public static void main(String[] args) {
        //CombinationCount.sum(array.length-1);
        //System.out.println(CombinationCount.count);
        System.out.println(CombinationCount.getCount());
    }
    
}







版权声明:本文为weiweiyixiaocsdn原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。