算法day22|组合总和 (含剪枝)、40.组合总和II、131.分割回文串

news2024/11/23 22:09:57

算法day22|组合总和 (含剪枝)、40.组合总和II、131.分割回文串

  • 39. 组合总和 (含剪枝)
  • 40.组合总和II
  • 131.分割回文串

39. 组合总和 (含剪枝)

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

输入: candidates = [2], target = 1
输出: []

提示:

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素 互不相同
  • 1 <= target <= 40
class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    int vectorSum(vector<int> path)
    {
        int sum=0;
        for(int i=0;i<path.size();i++)
        {
            sum+=path[i];
        }
        return sum;
    }
    void backtracking(vector<int>& candidates, int target,int startIndex)
    {
        if(vectorSum(path)==target)
        {
            result.push_back(path);
            return;
        }
        for(int i=startIndex;i<candidates.size();i++)
        {
            if(vectorSum(path)<target)
            path.push_back(candidates[i]);
            else
            break;
            backtracking(candidates,target,i);
            path.pop_back();
        }
        return;

    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        backtracking(candidates,target,0);
        return result;
    }
};

最主要的问题是:如何避免重复的组合?因为当循环到后面的数了,下面的递归还得从头开始,这就会造成组合重复。所以,关键的解决方法是:引入startIndex。标记每次循环的开始,让本层递归必须在上一次递归的数开始,而不是都从头开始,即:

for(int i=startIndex;i<candidates.size();i++)
     backtracking(candidates,target,i);

当上一次递归到 i 的时候,下一层递归就从 i 开始,如图(来自卡哥):

39.组合总和

最好画图来帮助理解。对于取和的操作,最好还是不要用函数,用变量sum,边遍历边求和,这样可以减少时间复杂度。

40.组合总和II

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

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

**注意:**解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30
class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    int sum=0;
    void backtracking(vector<int>& candidates, int target,int startIndex,vector<bool> &used)
    {
        if(sum==target)
        {
            result.push_back(path);
            return;
        }
        for(int i=startIndex;i<candidates.size();i++)
        {
            if(i>0&&candidates[i]==candidates[i-1]&&used[i-1]==false)
            continue;
            path.push_back(candidates[i]);
            sum+=candidates[i];
            used[i]=true;
            if(sum>target)
            {
                path.pop_back();
                sum-=candidates[i];
                used[i]=false;
                continue;
            }
            backtracking(candidates,target,i+1,used);
            path.pop_back();
            sum-=candidates[i];
            used[i]=false;
        }

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<bool> used(candidates.size(),false);
        sort(candidates.begin(),candidates.end());
        backtracking(candidates,target,0,used);
        return result;
    }
};

本题的关键:去重

方法:用一个布尔型数组,用来给candidates中的每一项做标记。

具体过程:

  • 首先,将candidates排序,使得重复的元素相邻(如果没有重复元素的话,正常处理是不会有重复组合的。),要知道,重复的组合都来自之后重复的元素(仔细想想其中的过程)

  • 然后,对vector作初始化,把所有的项都设为false

   vector<bool> used(candidates.size(),false);
  • 最后,在for循环中,当(i>0)candidates[i]==candidates[i-1]时,说明前后两个数是重复的项,那么问题来了:只要重复就要跳过吗?显然,如果是树枝重复,即在一个组合内有重复元素是OK的;而如果是树层重复,就会产生重复的组合了(想像一下),所以这种情况是不行的。所以判定条件为:
  if(i>0&&candidates[i]==candidates[i-1]&&used[i-1]==false)
      continue;

131.分割回文串

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是

回文串

。返回 s 所有可能的分割方案。

示例 1:

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a"
输出:[["a"]]

提示:

  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成
class Solution {
public:
    vector<string> path;
    vector<vector<string>> result;
    bool HuiWen(string s, int start,int end)
    {
        bool flag=true;
        for(int i=start,j=end;i<j;i++,j--)
        {
            if(s[i]!=s[j])
            flag=false;
        }
        return flag;
    }
    void backtracking(string s,int startIndex)
    {
        if(startIndex==s.size())
        {
            result.push_back(path);
            return;
        }
        for(int i=startIndex;i<s.size();i++)
        {
            if(HuiWen(s,startIndex,i))
            {
                string str=s.substr(startIndex,i-startIndex+1);
                path.push_back(str);
            }
            else
            continue;
            backtracking(s,i+1);
            path.pop_back();
        }
        return;
    }
    vector<vector<string>> partition(string s) {
        backtracking(s,0);
        return result;
    }
};

这题难度很大,熟能生巧吧。关键思路在于如何表示切割:用区间 [ startIndex , i ] 来表示,每次都切割这个区间内的字符串即可。能够不断重新切割的逻辑就是回溯,切完之后就回去了,重新让下一个 i 来切。

代码细节:

  • strsub()函数

s.substr (pos, n) ,pos表示要截取的字符串的开始的位置,n 代表要截取的字符串的长度

s.substr(pos) , 表示从pos位置开始的到字符串最后一位截取的字符串

string str=s.substr(startIndex,i-startIndex+1);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2109486.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Node-API实现跨语言交互开发流程

一、前言 使用Node-API实现跨语言交互&#xff0c;首先需要按照Node-API的机制实现模块的注册和加载等相关动作。 ArkTS/JS侧&#xff1a;实现C方法的调用。代码比较简单&#xff0c;import一个对应的so库后&#xff0c;即可调用C方法。 Native侧&#xff1a;.cpp文件&#xf…

【C语言】十六进制、二进制、字节、位、指针、数组

【C语言】十六进制、二进制、字节、位 文章目录 [TOC](文章目录) 前言一、十六进制、二进制、字节、位二、变量、指针、指针变量三、数组与指针四、指针自加运算五、二维数组与指针六、指向指针的指针七、指针变量作为函数形参八、函数指针九、函数指针数组十、参考文献总结 前…

JVM面试(六)垃圾收集器

目录 概述STW收集器的并发和并行 Serial收集器ParNew收集器Parallel Scavenge收集器Serial Old收集器Parallel Old收集器CMS收集器Garbage First&#xff08;G1&#xff09;收集器 概述 上一章我们分析了垃圾收集算法&#xff0c;那这一章我们来认识一下这些垃圾收集器是如何运…

某云彩SRM2.0任意文件下载漏洞

文章目录 免责申明搜索语法漏洞描述漏洞复现修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 搜索语法 fofa icon_hash"1665918155"漏洞描述 某云采 SRM2.0是一款先…

制作自己的游戏:打砖块

文章目录 &#x1f680; 前言&#x1f680; 前期准备&#x1f680; 玩法设计&#x1f680; 游戏场景&#x1f353; 什么是游戏场景&#x1f353; 绘制左上角积分&#x1f353; 绘制右上角生命值&#x1f353; 绘制砖块&#x1f353; 绘制小球&#x1f353; 绘制挡板&#x1f35…

场景是人工智能第四要素,是垂直领域人工智能的第一要素。

"场景是人工智能的第四要素&#xff0c;与数据、算力、算法同等重要。"拿着技术找场景&#xff0c;还是拿着场景找技术&#xff1f;这个锤子和钉子的问题&#xff0c;一直困扰着各家AI大厂。从近5年的实践来看&#xff0c;拿着场景找技术是更为稳健的&#xff0c;否则…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《面向电网调峰的聚合温控负荷多目标优化控制方法 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

R901085689比例流量控制阀配置HE-SP1比例放大器

R901085689比例流量控制阀配置HE-SP1比例放大器的功能是将电信号转换成对应的流量变化&#xff0c;通过调整阀门开度来控制介质的流量。这种转换是通过比例电磁铁实现的&#xff0c;它将输入的电流信号转换成力或位移&#xff0c;从而驱动阀芯移动&#xff0c;实现流量的连续调…

html+css+js网页设计 珠宝首饰模版13个页面

htmlcssjs网页设计 珠宝首饰模版13个页面 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&…

手机同时传输USB功能与充电的实现及LDR6500的作用

在智能设备日益普及的今天&#xff0c;用户对于手机的功能需求愈发多样化&#xff0c;其中同时实现USB数据传输与充电功能成为了许多用户的迫切需求。这一功能的实现离不开先进的硬件技术和创新的芯片解决方案&#xff0c;而LDR6500正是这样一款能够满足这一需求的USB PD&#…

uni-app 扫码优化:谈谈我是如何提升安卓 App 扫码准确率的

一. 前言 之前的一个项目遭到用户吐槽&#xff1a;“你们这个 App 扫码的正确率太低了&#xff0c;尤其是安卓的设备。经常性的扫码扫不出来&#xff0c;就算是扫出来了&#xff0c;也是错误的结果&#xff01;” 由于之前是扫描二维码的需求&#xff0c;所以没有对扫描条形码…

yolov8-obb旋转目标检测onnxruntime和tensorrt推理

onnxruntime推理 导出onnx模型&#xff1a; from ultralytics import YOLO model YOLO("yolov8n-obb.pt") model.export(format"onnx") onnx模型结构如下&#xff1a; python推理代码&#xff1a; import cv2 import math import numpy as np impo…

全面提升管理效率的智慧园区可视化系统

通过图扑 HT 搭建智慧园区可视化&#xff0c;实时监测和展示园区内各设施的状态与能耗&#xff0c;优化资源配置&#xff0c;提升园区管理效率。

科普神文,一次性讲透AI大模型的核心概念

令牌&#xff0c;向量&#xff0c;嵌入&#xff0c;注意力&#xff0c;这些AI大模型名词是否一直让你感觉熟悉又陌生&#xff0c;如果答案肯定的话&#xff0c;那么朋友&#xff0c;今天这篇科普神文不容错过。我将结合大量示例及可视化的图形手段&#xff0c;为你由浅入深一次…

电脑怎么禁止软件联网?电脑怎么限制软件上网?方法很多,这三种最常用!

在日常使用电脑时&#xff0c;某些软件可能会自动联网&#xff0c;这不仅会消耗网络资源&#xff0c;还可能带来安全风险。此外企业老板考虑到公司员工可能会在工作期间访问无关软件&#xff0c;影响工作效率&#xff0c;因此&#xff0c;很多用户希望能够禁止某些软件联网&…

springboot学生社团管理系统—计算机毕业设计源码26281

目录 摘要 Abstract 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 学生社团管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析…

C语言 10 数组

简单来说&#xff0c;数组就是存放数据的一个组&#xff0c;所有的数据都统一存放在这一个组中&#xff0c;一个数组可以同时存放多个数据。 一维数组 比如现在想保存 12 个月的天数&#xff0c;那么只需要创建一个 int 类型的数组就可以了&#xff0c;它可以保存很多个 int …

Linux网络编程IO管理

网络 IO 涉及到两个系统对象&#xff0c;一个是用户空间调用 IO 的进程或者线程&#xff0c;一个是内核空间的内核系统&#xff0c;比如发生 IO 操作 read 时&#xff0c;它会经历两个阶段&#xff1a; 等待内核协议栈的数据准备就绪&#xff1b;将内核中的数据拷贝到用户态的…

vue3 json格式化显示数据(vue3-json-viewer) 对比修改前后数据

需求&#xff1a;对比变更前后数据 npm包下载 npm install vue3-json-viewer --savemain.ts中全局引用 // json可视化 import JsonViewer from "vue3-json-viewer" import "vue3-json-viewer/dist/index.css";app.use(JsonViewer).mount("#app&quo…

鸿蒙界面开发——组件(6):属性字符串(StyledString)文本输入

属性字符串StyledString/MutableStyledString MutableStyledString继承于StyledString&#xff0c;以下统一简称StyledString。 是功能强大的标记对象&#xff0c;可用于字符或段落级别设置文本样式。 通过将StyledString附加到文本组件&#xff0c; 可以通过多种方式更改文本…