Combination Sum (LeetCode)

Question:

https://oj.leetcode.com/problems/combination-sum/

 

这种一般就是backtracking,可以iterative或者recursive.

 

1. Iterative解法,需要用stack保存上一个数的index。

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        vector<vector<int>> result;
        vector<int> list;
        
        combiterdfs(result, candidates, target);
        
        return result;
    }
    
    struct Node
    {
        vector<int> list;
        int sum;
    };
        
    void combiterdfs(vector<vector<int>>& result, vector<int>& candidates, int target)
    {
        if (candidates.empty())
            return;
        
        stack<int> s;
        Node node;
        node.sum = 0;   // init to zero!!!!
        
        PushNode(s, candidates, node, 0);

        while (!s.empty())
        {
            if (node.sum >= target)
            {
                if (node.sum == target)
                {
                    result.push_back(node.list);
                }
                
                // pop the top node
                PopNode(s, candidates, node);
                
                //Keep poping if the expected new index (s.top()+1) is same as candidates.size()
                while (!s.empty() && s.top() == candidates.size()-1)
                {
                    PopNode(s, candidates, node);
                }
                
                if (s.empty())
                    break;
                    
                IncTopNode(s, candidates, node);
            }
            else
            {
                PushNode(s, candidates, node, s.top());
            }
        }
    }
    
    void PopNode(stack<int>& s, vector<int>& candidates, Node& node)
    {
        int index = s.top();
        s.pop();
        node.sum -= candidates[index];
        node.list.pop_back();
    }
    
    void PushNode(stack<int>& s, vector<int>& candidates, Node& node, int index)
    {
        s.push(index);
        node.sum += candidates[index];
        node.list.push_back(candidates[index]);
    }
    
    void IncTopNode(stack<int>& s, vector<int>& candidates, Node& node)
    {
        int index = s.top();
        s.top()++;
        
        node.sum += (candidates[index+1] - candidates[index]);
        node.list.pop_back();
        node.list.push_back(candidates[index+1]);
    }

 

2. Recurisve

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        vector<vector<int>> result;
        vector<int> list;
        
        std::sort(candidates.begin(), candidates.end());

        for (int i = 0; i < candidates.size(); i++)
        {
            combRecur(result, list, 0, candidates, i, target);
        }
        
        return result;
    }

    void combRecur(vector<vector<int>>& result, vector<int>& list, int sum, vector<int>& candidates, int pos, int target)
    {
        list.push_back(candidates[pos]);
        sum += candidates[pos];

        if (sum == target)
        {
            result.push_back(list);
        }
        else if (sum < target)
        {
            for (int i = pos; i < candidates.size(); i++)
            {
                combRecur(result, list, sum, candidates, i, target);
            }
        }
        
        list.pop_back();
        return;
    }

 

posted @ 2015-01-29 13:18  smileheart  阅读(167)  评论(0)    收藏  举报