• 2021.3.16 刷题--组合总和||(一种组合下元素不可重复选取)


    题目链接:https://leetcode-cn.com/problems/combination-sum-ii
    题目描述:
    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的每个数字在每个组合中只能使用一次。

    说明:
    所有数字(包括目标数)都是正整数。
    解集不能包含重复的组合。

    示例 1:
    输入: candidates = [10,1,2,7,6,1,5], target = 8,
    所求解集为:
    [
    [1, 7],
    [1, 2, 5],
    [2, 6],
    [1, 1, 6]
    ]

    示例 2:
    输入: candidates = [2,5,2,1,2], target = 5,
    所求解集为:
    [
      [1,2,2],
      [5]
    ]

    题解:

    
    class Solution {
    public:
        vector<int> ans;
        vector<int> candidates;
        vector<vector<int>> result;
        void solve(int target, int index)
        {
            if(target == 0)
                result.push_back(ans);
            for(int i = index; i < candidates.size(); i++)
            {
                if(target - candidates[i] < 0)
                    break;
                if(i > index && candidates[i] == candidates[i - 1])
                    continue;
                ans.push_back(candidates[i]);
                solve(target - candidates[i], i + 1);
                ans.pop_back();
            }
        }
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            sort(candidates.begin(), candidates.end());
            this->candidates = candidates;
            solve(target, 0);
            return result;
        }
    };
    
    class Solution {
    public:
        vector<vector<int>> ans;
        vector<int> path;
        void trackingback(vector<int>& candidates, int startIndex, int sum, int target, vector<bool>& used)
        {
            if(sum == target)
            {
                ans.push_back(path);
      
              return;
            }
            
            for(int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++)
            {
                //used[i - 1] == true,表明在递归时该元素被使用,即在同一树支中被使用,下一层若有重复元素依旧可以使用
                //used[i - 1] == false,表明在递归中该元素被使用且被回退,即在同一树层使用过,若有重复元素不可使用
                if(i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false)
                {
                    continue;
                }
                sum += candidates[i];
                path.push_back(candidates[i]);
                used[i] = true; //标记该位元素被使用
                trackingback(candidates, i + 1, sum, target, used);
                used[i] = false; //回溯,取消该元素被使用标记
                sum -= candidates[i];
                path.pop_back();
            }
        }
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            vector<bool> used(candidates.size(), false);  //标记
            sort(candidates.begin(), candidates.end());  //排序
            trackingback(candidates, 0, 0, target, used);
            return ans;
        }
    };
    
  • 相关阅读:
    JavaScript算法学习:获取字符串最后一位方法及判断是否以指定字符串开始或结尾
    前端基础知识学习笔记
    JavaScript算法练习:找出字符串中最长的单词并输出其长度
    HTML+CSS学习笔记
    Mint-ui中loadmore(上拉加载下拉刷新)组件在ios中滑动会触发点击事件的解决方法
    JavaScript中的DOM,BOM详细介绍;
    web前端面试题目整理
    Charles https乱码处理
    String类的三个参数的构造方法
    java.net包中的URL类
  • 原文地址:https://www.cnblogs.com/ZigHello/p/14542291.html
Copyright © 2020-2023  润新知