【LeetCode】39. Combination Sum 目标数字的加数分解

一、概述

输入一个数组和一个数字,在数组中找到所有数字组合,组合中元素之和等于输入的数字。

一看就是DFS,没的说。关键是DFS如何优化。

我的DFS效果不咋地:

【LeetCode】39. Combination Sum 目标数字的加数分解_第1张图片

那就拿这道题来看看怎么优化吧。时间缩短了三倍。

【LeetCode】39. Combination Sum 目标数字的加数分解_第2张图片

二、分析

1、我的算法

仅仅简单的DFS是完全不够用的。一定需要剪枝。我选择的剪枝方法是基于输入数组的有序性做的:

对数组进行遍历,如果当前和加上当前的数组元素比target大,那之后的元素就不用看了。用这种方法剪枝。

代码如下:

class Solution {
    vector> result;
public:
    vector> combinationSum(vector& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector nowsum;
        DFS(0,candidates,0,target,nowsum);
        return result;
    }
    void DFS(int i,vector candidates,int nowsum,int target,vector nowcom)
    {
        if(nowsum==target)
        {
            result.push_back(nowcom);
            return;
        }
        else
        {
            for(int j=i;jtarget)
                    break;
                else
                {
                    nowcom.push_back(candidates[j]);
                    DFS(j,candidates,nowsum+candidates[j],target,nowcom);
                    nowcom.pop_back();
                }
            }
        }
    }
};

很慢,但是我觉得再剪枝也减不下去了,别的优化方式也不会,所以就僵住了。

2、较好的方法

直接看代码,算法思路都一样。

class Solution {
public:
    vector> combinationSum(vector& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        vector> res;
        vector input;
        helper(candidates, input, target, 0, res);
        return res;
    }
    
    void helper(vector &candidates, vector &input, int target, int idx, vector> &res)
    {
        if (target == 0)
        {
            res.push_back(input);
            return;
        }
        
        for (int i=idx; i target)
                break;
            input.push_back(val);
            helper(candidates, input, target - val, i, res);
            input.pop_back();
        }
    }
};

和我的代码只在细节上有差异。

第一,参数使用引用。在我的函数中,candidates和nowcom使用引用之后,耗时就直接由24ms到8ms,空间消耗也减了一半,十分优秀。

第二,用减法代替加法,我没弄明白这个的优势在哪里。

反正用引用就对了。

三、总结

在DFS之类调用函数时,函数参数如果有向量之类,使用引用会更好。

你可能感兴趣的:(LeetCode)