组合总和问题---一个数字可重复选择多次

leetcode 39. Combination Sum

一、问题描述

    给定一组数(数字没有重复)和一个目标值,找到数字中和为目标值的所有唯一组合。一个数字可以重复选择多次。
  【注意】

  •         所有数字(包括目标)都是正整数。
  •         结果集不能包含重复的组合。
【举例】
例1:输入: candidates = [2,3,6,7], target = 7,
输出解集:
[
  [7],
  [2,2,3]
]
例2:输入: candidates = [2,3,5], target = 8,
输出解集:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

二、问题分析

由于要输出所有解集具体组合而不是解集个数,因此采用dfs的方法,边递归边记录结果

三、算法实现

/*********************************************************
Author:tmw
date:2018-5-14
*********************************************************/
#include <stdio.h>
#include <stdlib.h>

/**
    *final_r_perLen :存储每一组最终结果的长度
    **final_r       :存储所有结果的数组
    start           : 当前递归起始位置
**/
#define MAX_SIZE 200
int result[MAX_SIZE] = {0}; /**存储中间结果的数组**/
int j=0;                    /**结果数组下标**/
int count = 0;              /**记录所有可能的组合个数**/
void sum_dfs( int* array, int array_len, int sum, int start, int** final_r, int* final_r_perLen )
{
    /**终止条件**/
    if( sum == 0 )
    {
        int i;
        for( i=0; i<j; i++ )
            final_r[count][i] = result[i];

        final_r_perLen[count] = j;
        count++;
        return;
    }

    int k;
    for( k=start; k<array_len; k++ )
    {
        /**收敛条件---剪枝**/
        if( array[k]>sum ) return;

        /**将当前元素加入中间结果数组**/
        result[j++] = array[k];
        sum_dfs(array,array_len,sum-array[k],k,final_r,final_r_perLen);

        j--; /**j回退到递归之前的状态**/
    }
}

/**快排**/
#define swap( x,y,t ) (t=x,x=y,y=t)
int fast_sort_one( int* array, int low, int high )
{
    int target = array[low];
    int temp;
    while( low < high )
    {
        if( low<high && array[high]>=target )
            high--;
        swap(array[low],array[high],temp);
        if( low<high && array[low]<=target )
            low++;
        swap(array[low],array[high],temp);
    }
    return low;
}
void fast_sort_all( int* array, int low, int high )
{
    if( low<high )
    {
        int mid_index = fast_sort_one(array,low,high);
        fast_sort_all(array,low,mid_index-1);
        fast_sort_all(array,mid_index+1,high);
    }
}

int** combinationSum(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize)
{
    printf("%d\n",candidatesSize);
    fast_sort_all(candidates,0,candidatesSize-1);
    int i;

    int* final_r_perLen = (int*)malloc(MAX_SIZE*sizeof(int));
    int** final_r = (int**)malloc(MAX_SIZE*sizeof(int*));

    for( i=0; i<MAX_SIZE; i++ )
        final_r[i] = (int*)malloc(MAX_SIZE*sizeof(int));

    count = 0; /**全局变量count清零**/
    sum_dfs(candidates,candidatesSize,target,0,final_r,final_r_perLen);

    *columnSizes = (int*)malloc(count*sizeof(int));
    for(i=0; i<count; i++)
        (*columnSizes)[i] = final_r_perLen[i];
    *returnSize = count;

    return final_r;
}

四、执行结果

leetcode accept


梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~

猜你喜欢

转载自blog.csdn.net/qiki_tangmingwei/article/details/80328931