当前位置: 首页 > news >正文

【算法与数据结构】40、LeetCode组合总和 II

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述

二、解法

  思路分析:【算法与数据结构】39、LeetCode组合总和的基础之上,这道题变成了candidates中有重复元素,而且每个元素只能使用一次。如果直接使用39题的代码会出现重复的组合,需要去重,但这样一来leetcode可能运行超时。因此我们需要再找组合的时候就进行去重的操作。引入一个used布尔数组,标记candidates中的元素是否使用过。在这之前首先需要对candidates数组进行排序。

  例如, target=7, candidates = [1 1 2 4 5 7], 第一种情况:candidates[0] +candidates[2] + candidates[3] = candidates[1] +candidates[2] + candidates[3]= 1 + 2 + 4, 因此出现重复的组合。第二种情况:candidates[0] +candidates[1] + candidates[4]= 1 + 1 + 5是无重复的组合。因此用used标记使用过的数,当candidates[i] == candidates[i - 1]时,出现重复元素。进行第i次循环时,第一种情况used[i-1]=false就是出现重复组合, 在第i-1次循环时已经考虑过了,直接continue。第二种情况就是重复数字都利用到了used[i-1]=true,这种需要考虑。
  程序如下

class Solution {
private:vector<vector<int>> result;     // 结果合集vector<int> path;void backtracking(const vector<int>& candidates, const int target, int sum, int startIndex, vector<bool>& used) {if (sum > target) return;    // 剪枝if (sum == target) {result.push_back(path);return;}for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) { // 剪枝优化if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {	// 去重continue; }sum += candidates[i];used[i] = true;path.push_back(candidates[i]);  // 处理节点backtracking(candidates, target, sum, i+1, used);  // 递归used[i] = false;sum -= candidates[i];path.pop_back();    // 回溯,撤销处理的节点}}
public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool>used(candidates.size(), 0);sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0, used);return result;}
};

复杂度分析:

  • 时间复杂度: O ( n ∗ 2 n ) O(n*2^n) O(n2n)
  • 空间复杂度: O ( n ) O(n) O(n)

三、完整代码

# include <iostream>
# include <vector>
# include <string>
# include <algorithm>
using namespace std;class Solution {
private:vector<vector<int>> result;     // 结果合集vector<int> path;void backtracking(const vector<int>& candidates, const int target, int sum, int startIndex, vector<bool>& used) {if (sum > target) return;    // 剪枝if (sum == target) {result.push_back(path);return;}for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) { // 剪枝优化if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {	// 去重continue; }sum += candidates[i];used[i] = true;path.push_back(candidates[i]);  // 处理节点backtracking(candidates, target, sum, i+1, used);  // 递归used[i] = false;sum -= candidates[i];path.pop_back();    // 回溯,撤销处理的节点}}
public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool>used(candidates.size(), 0);sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0, used);return result;}
};int main() {vector<int> candidates = { 10,1,2,7,6,1,5 };int target = 8;Solution s1;vector<vector<int>> result = s1.combinationSum2(candidates, target);for (vector<vector<int>>::iterator it = result.begin(); it != result.end(); it++) {for (vector<int>::iterator jt = (*it).begin(); jt != (*it).end(); jt++) {cout << *jt << " ";}cout << endl;}system("pause");return 0;
}

end

http://www.lryc.cn/news/225707.html

相关文章:

  • Flink SQL -- 命令行的使用
  • asp.net core把所有接口和实现类批量注入到容器
  • SPSS曲线回归
  • 软件之禅(七)面向对象(Object Oriented)
  • 汽车之家车型_车系_配置参数数据抓取
  • RabbitMQ的 五种工作模型
  • 原型制作神器ProtoPie的使用Unity与网页跨端交互
  • 另辟奚径-Android Studio调用Delphi窗体
  • SOLID 原则,程序设计五大原则,设计模式
  • Java基础——数组(一维数组与二维数组)
  • Python爬虫抓取微博数据及热度预测
  • Qt QTableWidget表格的宽度
  • OpenCV(opencv_apps)在ROS中的视频图像的应用(重点讲解哈里斯角点的检测)
  • 常见排序算法之插入排序类
  • Dubbo服务消费端远程调用过程剖析
  • 华硕荣获“EPEAT Climate+ Champion”永续先驱称号
  • 基于QT使用OpenGL,加载obj模型,进行鼠标交互
  • 三大赛题指南发布!2023 冬季波卡黑客松本周末开启 Workshop
  • 数据结构与算法(Java版) | 算法的空间复杂度简介
  • 大数据-之LibrA数据库系统告警处理(ALM-12037 NTP服务器异常)
  • 烟草5G智慧工厂数字孪生可视化平台,赋能烟草工业数字化智慧转型
  • PHP编写采集药品官方数据的程序
  • 解决Jenkins执行git脚本时报错:No such device or address问题
  • LCD英文字模库(16x8)模拟测试程序
  • 二分法
  • Linux文件类型与权限及其修改
  • RPC 框架 openfeign 介绍和学习使用总结
  • 大厂真题:【DP/贪心】字节跳动2023秋招-小红的 01 串
  • 【技术类-01】doc转PDF程序卡死的解决方案,
  • 探索未来,开启无限可能:打造智慧应用,亚马逊云科技大语言模型助您一臂之力