【一天一道LeetCode】#39. Combination Sum

一天一道LeetCode系列

(一)题目

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 (a1, a2, … , 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]

(二)解题


/*

主要思路:

1.对目标vector排序,定义一个临时的vector容器tmp

2.采用动态规划和回溯法的方法,对于当前要添加到tmp的数num

(1)如果target<num,return;

(2)如果target>num,则继续在num和num以后的数中选择一个数相加;(此处需要考虑可以重复的组合)

(3)如果target==num,则代表找到

对于(2),(3)递归完成后需要将压入的数弹出,即采用回溯法的思想

*/


class Solution {

public:

    vector<vector<int>> ret;//结果

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {

        sort(candidates.begin(),candidates.end());//首先进行排序

        for(int idx = 0;idx<candidates.size();idx++)

        {

           if(idx-1>=0 && candidates[idx] == candidates[idx-1]) continue;//避免重复查找

           else{

               if(candidates[idx]<=target){//如果小于则调用动态规划函数

                  vector<int> tmp;

                  tmp.push_back(candidates[idx]);

                  combinationDfs(candidates,tmp,idx,target-candidates[idx]); 

               }

           }

        }

        return ret;

    }

    /*candidates为目标vector

    tmp为临时vector变量,存储找到的组合

    start是初始序号,代表在start及其以后的数字中查找

    target是当前需要在candidates中查找的数

    */

    void combinationDfs(vector<int>& candidates , vector<int>& tmp , int start,int target)

    {

        if(target == 0){//如果target等于0,代表第一个数就满足

            ret.push_back(tmp);

            return;

        }

        for(int idx = start;idx<candidates.size();idx++)

        {

            if(target > candidates[idx])

            {

                tmp.push_back(candidates[idx]);

                combinationDfs(candidates,tmp,idx,target-candidates[idx]);

                tmp.pop_back();//回溯法,要pop出最后压入的元素

            }

            else if(target == candidates[idx])//等于target代表以及找到

            {

                tmp.push_back(candidates[idx]);

                ret.push_back(tmp);

                tmp.pop_back();//回溯法,要pop出最后压入的元素

            }

            else if(target < candidates[idx])

            {

                return;

            }

        }

    }

};
给定一个整数数组 nums 和一个目标值 target,要求在数组中找出两个数的和等于目标值,并返回这两个数的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历数组的所有组合,判断两个数的和是否等于目标值。如果等于目标值,则返回这两个数的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储数组中的元素和对应的索引。遍历数组,对于每个元素nums[i],我们可以通过计算target - nums[i]的值,查找哈希表中是否存在这个差值。 如果存在,则说明找到了两个数的和等于目标值,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果数组已经排序,可以使用双指针的方法来求解。假设数组从小到大排序,定义左指针left指向数组的第一个元素,右指针right指向数组的最后一个元素。 如果当前两个指针指向的数的和等于目标值,则返回它们的索引。如果和小于目标值,则将左指针右移一位,使得和增大;如果和大于目标值,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个数的和等于目标值或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果数组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果数组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值