LeetCode | Combination Sum(元素的和)

Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.

For example, given candidate set 2,3,6,7 and target 7
A solution set is: 
[7] 
[2, 2, 3] 

题目解析:

让在数组中找到合适的数据,让其等于给定值target。就是应用深度优先算法,选择一个元素,再递归进去。但是仅考虑到这里的话,会造成重复:223和232等。那么在下一层递归的时候,从k开始到n-1遍历。这样就不会有重复结果了。


#include <stdio.h>
#include <stdlib.h>

struct Stk{
    int arr[20];
    int len;
};

void Print(struct Stk *stack)
{
    for(int i = 0;i < stack->len;i++){
        printf("%d ",stack->arr[i]);
    }
    printf("\n");

}
//n-数组长度,sum剩余要求的和,递归遍历时从k索引开始遍历到n-1,避免重复,stack为栈。
void DFS(int arr[],int n,int sum,int k,struct Stk *stack)
{
    for(int i = k;i < n;i++){
        if(arr[i] == sum){  //当正好为剩余数的和,就先入栈,再打印,再出栈,最后返回,因为后面的数更大
            stack->arr[stack->len] = arr[i];
            stack->len++;
            Print(stack);
            stack->len--;
            return;
        }
        if(arr[i] < sum){   //递归含义,选择后递归,然后退出,再遍历后续元素
            stack->arr[stack->len++] = arr[i];
            DFS(arr,n,sum-arr[i],i,stack);
            stack->len--;
        }else{  //当arr[i] > sum 时,就退出,不对后面更大的数进行判断。
            break;
        }
    }
}

int main()
{
    int arr[] = {2,3,6,7};
    int n = sizeof(arr)/sizeof(int);
    int sum;
    struct Stk stack;
    stack.len = 0;
    while(scanf("%d",&sum)){
        DFS(arr,n,sum,0,&stack);

    }

    return 0;
}

正统的递归方式

class Solution {
public:
    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        sort(candidates.begin(), candidates.end());
        vector<int>::iterator pos = unique(candidates.begin(), candidates.end());
        candidates.erase(pos, candidates.end());
        vector<vector<int> > ans;
        vector<int> record;
        searchAns(ans, record, candidates, target, 0);
        return ans;
    }
    
private:
    void searchAns(vector<vector<int> > &ans, vector<int> &record, vector<int> &candidates, int target, int idx) {
        if (target == 0) {
            ans.push_back(record);
            return;
        }
        if (idx == candidates.size() || candidates[idx] > target) {
            return;
        }
        for (int i = target / candidates[idx]; i >= 0; i--) {
            record.push_back(candidates[idx]);            
        }
        for (int i = target / candidates[idx]; i >= 0; i--) {
            record.pop_back();
            searchAns(ans, record, candidates, target - i * candidates[idx], idx + 1);            
        }
    }
};

点赞