代码随想录算法训练营第二十七天|39. 组合总和 40.组合总和II131.分割回文串

news2024/11/27 3:50:48

文章目录

  • 39. 组合总和
    • 思路
    • 代码
    • 总结
  • 40.组合总和II
    • 思路
    • 代码
    • 总结
  • 131.分割回文串
    • 思路
    • 代码
    • 总结

39. 组合总和

思路

我举过例子,如果是一个集合来求组合的话,就需要startIndex,例如:77.组合 ,216.组合总和III 。

如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:17.电话号码的字母组合

剪枝优化:对于sum已经大于target的情况,其实是依然进入了下一层递归,只是下一层递归结束判断的时候,会判断sum > target的话就返回。
其实如果已经知道下一层的sum会大于target,就没有必要进入下一层递归了。
那么可以在for循环的搜索范围上做做文章了。
对总集合排序之后,如果下一层的sum(就是本层的 sum + candidates[i])已经大于target,就可以结束本轮for循环的遍历。

代码

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startidx) {
        if(sum > target) return;

        if(sum == target) {
            result.push_back(path);
            return;
        }

        for ( int i = startidx; i < candidates.size(); i++) {
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracking(candidates,target,sum,i);
            sum -= candidates[i];
            path.pop_back();
        }
        
    }

public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        result.clear();
        path.clear();
        backtracking(candidates,target,0,0);
        return result;
    }
};

总结

  1. 在求和问题中,排序之后加剪枝是常见的套路!

40.组合总和II

思路

树层去重的话,需要对数组排序!
在这里插入图片描述

代码

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startidx, vector<bool>& used ) {
        if(sum > target) {
            return;
        }
        if(sum == target) {
            result.push_back(path);
            return;
        }

        for(int i = startidx; 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);
            // 回溯
            sum -= candidates[i];
            used[i] = false;
            path.pop_back();
        }

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        result.clear();
        path.clear();
        vector<bool> used(candidates.size(),false);

        // 要先排序,让相同的元素挨在一起
        sort(candidates.begin(),candidates.end());

        backtracking(candidates,target,0,0,used);
        return result;
    }
};

总结

  1. 直接用startIndex来去重也是可以的, 就不用used数组了。剩下一个数组的空间
  2. 注意排序
  3. 树层去重与树枝去重的区别

131.分割回文串

思路

  1. 切割问题,有不同的切割方式
  2. 判断回文

切割问题实际上也是一种组合问题

回文问题的优化:给定一个字符串s, 长度为n, 它成为回文字串的充分必要条件是s[0] == s[n-1]且s[1:n-1]是回文字串。
大家如果熟悉动态规划这种算法的话, 我们可以高效地事先一次性计算出, 针对一个字符串s, 它的任何子串是否是回文字串, 然后在我们的回溯函数中直接查询即可, 省去了双指针移动判定这一步骤
优化后的回文判断方法代码:

 void computePalindrome(const string& s) {
        // isPalindrome[i][j] 代表 s[i:j](双边包括)是否是回文字串 
        isPalindrome.resize(s.size(), vector<bool>(s.size(), false)); // 根据字符串s, 刷新布尔矩阵的大小
        for (int i = s.size() - 1; i >= 0; i--) { 
            // 需要倒序计算, 保证在i行时, i+1行已经计算好了
            for (int j = i; j < s.size(); j++) {
                if (j == i) {isPalindrome[i][j] = true;}
                else if (j - i == 1) {isPalindrome[i][j] = (s[i] == s[j]);}
                else {isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i+1][j-1]);}
            }
        }
    }

代码

class Solution {
private:
    vector<vector<string>> result;
    vector<string> path;

    void backtracking (string s, int startidx) {
        if(startidx >= s.size()) {
            result.push_back(path);
            return;
        }

        for(int i = startidx; i < s.size(); i++ ){
            if(isPalindrome(s,startidx,i)) {
                string str = s.substr(startidx, i - startidx + 1);
                path.push_back(str);
            }
            else {
                continue;
            }

            backtracking(s,i+1);
            path.pop_back();
        }
    }

    bool isPalindrome(string& s, int start, int end) {
        for ( int i = start, j = end; i < j; i++, j--) {
            if(s[i] != s[j]) {
                return false;
            }
        }
        return true;
    }
public:
    vector<vector<string>> partition(string s) {
        result.clear();
        path.clear();
        backtracking(s,0);
        return result;
    }
};

总结

  1. 优化版的回文操作是动态规划问题,虽然理解意思了,但是不太会
  2. 代码细节中有很多重点,但是写的时候没感觉到?

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

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

相关文章

【AIGC使用教程】Microsoft Edge/Bing Chat 注册使用完全指南

欢迎关注【AIGC使用教程】 专栏 【AIGC使用教程】SciSpace 论文阅读神器 【AIGC使用教程】Microsoft Edge/Bing Chat 注册使用完全指南 【AIGC使用教程】GitHub Copilot 免费注册及在 VS Code 中的安装使用 【AIGC使用教程】GitHub Copilot 免费注册及在 PyCharm 中的安装使用 …

算法时间复杂度

参考视频&#xff1a;https://www.bilibili.com/video/BV14j411f7DJ 目录 1.常数阶O(1) 2.对数阶O(IogN) 3.线性阶O(n) 4.线性对数阶O(nlogN) 5.平方阶O(n^2) 6.立方阶O(n^3) 7.K次方阶O(n^k) 8.指数阶(2^n) 9.阶乘O(n!) 两层for循环 for (int i 1; i <…

有模型强化学习和免模型强化学习有什么区别?

有模型强化学习&#xff08;Model-Based Reinforcement Learning&#xff09;和无模型强化学习&#xff08;Model-Free Reinforcement Learning&#xff09;是两种不同的强化学习方法。 有模型强化学习是指&#xff0c;智能体在学习过程中能够对环境进行建模&#xff0c;即学习…

软件测试分类: 你需要知道的不同类型测试

文章目录 一. 按测试对象进行划分1. 界面测试2. 可靠性测试3. 容错性4. 文档测试5. 兼容性测试6. 易用性测试7. 安装卸载的测试8. 安全测试9. 性能测试10. 内存泄漏测试 二. 按是否查看代码划分1. 黑盒测试(Black-box Testing)2. 白盒测试(White-box Testing)冒泡排序测试用例进…

【1 Vue基础 - 模板语法-绑定】

1 VSCode代码片段 链接: link 2 Mustache双大括号语法 插入内容 <body><div id"app"><!-- 1.基本使用 --><h2>{{ message }}</h2><h2>当前计数: {{ counter }} </h2><!-- 2.表达式 --><h2>计数双倍: {{ c…

研发项目工时统计工具哪个好?9大工时管理系统盘点

工时管理是项目型企业的重要需求&#xff0c;特别是在人力成本占比较高的行业&#xff0c;如软件开发、设计咨询、会计律师等。工时管理可以帮助企业核算项目人工成本&#xff0c;控制成本投入&#xff0c;提高项目利润&#xff0c;客观考核员工绩效&#xff0c;优化资源分配等…

C++类和对象入门(中)

C类和对象入门 中 1. 类的6个默认成员函数2. 构造函数2.1 概念2.2 特性 3.初始化列表4.析构函数4.2 特性 5. 拷贝构造函数5.1 特性 6.运算符重载6.1 赋值运算符重载6.2前置和后置重载 7. 自实现日期类 1. 类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空…

golang 服务中 context 超时处理的思考

文章目录 前言起因&#xff1a;日志告警引发的思考什么是contextcontext的作用context超时之后继续执行 or 中断 最后 前言 公司运行的服务代码中&#xff0c;随处可见各种各样的日志信息&#xff0c;其中大多数是用来记录各种异常的日志&#xff0c;一方面&#xff0c;当出现…

煤矿电子封条实施方案 yolov7

煤矿电子封条实施方案采用YOLOv7网络模型算法技术&#xff0c;煤矿电子封条实施算法模型过将全国各省矿山实时监测数据&#xff0c;实现对全国各矿山及时有效的处理及分析。YOLOv7 的发展方向与当前主流的实时目标检测器不同&#xff0c;研究团队希望它能够同时支持移动 GPU 和…

Arthas实现热更新代码

目录 1.Arthas简介 2.准备Demo 3.启动Arthas 4.Arthas命令 5.使用retransform命令热更新代码 1.Arthas简介 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对…

Python中的模块2

为了加快导入模块的速度&#xff0c;Python会缓存之前使用过的模块。 1 保存缓存文件的路径 Python会将之前编译过的模块保存在与该模块同一目录中的“__pycache__”文件夹中。 2 缓存文件名 缓存文件会以“模块名.版本号.pyc”格式命名。图1为使用yang_module.py模块后得到…

2023年NOC大赛创客智慧编程赛项图形化复赛模拟题一,包含答案解析

2023年NOC大赛创客智慧编程赛项图形化复赛模拟题一,包含答案解析 本次题目来源:NOC 大赛创客智慧编程赛项图形化复赛模拟题(一) 第一题: 制作一个生日贺卡小程序. 1.点击绿旗后蛋糕出现在 (0,-80) 的位置,大小为 100,造型为 cake-b2.当碰到鼠标指针时,将造型切换为 ca…

【EasyAR实战项目】图像识别+模型交互(全网首发,保姆级教程)

话不多说&#xff0c;先看实现效果 开发准备 以下为作者开发的环境&#xff0c;当然也可以使用更高的版本&#xff0c;尤其是EasyAR的版本可以选择更高的&#xff0c;因为这玩意儿版本迭代的太快了&#xff0c;而且更高版本所支持的手机型号更新&#xff0c;兼容性更强。 1 U…

SpringBoot实现限流注解

SpringBoot实现限流注解 在高并发系统中&#xff0c;保护系统的三种方式分别为&#xff1a;缓存&#xff0c;降级和限流。 限流的目的是通过对并发访问请求进行限速或者一个时间窗口内的的请求数量进行限速来保护系统&#xff0c;一旦达到限制速率则可以拒绝服务、排队或等待…

MySQL---存储引擎

1. 存储引擎 数据库存储引擎是数据库底层软件组织&#xff0c;数据库管理系统使用数据引擎进行创建、查询、更新和删 除数据。 不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能。不同的数据库管理系统都支持 多种不同的数据引擎。MySQL的核心就是存储引擎。 …

IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍

文章目录 前言 一、Idea创建项目的操作 1、选择本地的Scala插件包 2、创建项目的操作 3、输入新建的项目名称 4、在文件file里面选择new一个新的module文件 5、输入项目的名称&#xff0c;点击下一步 6、创建一个Scala文件夹 7、选择Mark directory as 8、单击文件里…

【5.21】六、自动化测试—概述

目录 6.1 自动化测试概述 6.1.1 什么是自动化测试 6.1.2 自动化测试的基本流程 6.1.3 自动化测试实施策略 6.1.4 自动化测试的优势和劣势 测试中的许多操作都是重复性的、非智力性的和非创造性的&#xff0c;但要求工作准确细致&#xff0c;此时计算机最适合代替人工去完成…

SpringBoot2.6.3集成ElasticSearch7.13.4详解,上下两篇,上篇集群配置,下篇集成配置(上)

一、集群配置准备 &#xff08;1&#xff09;方式一&#xff0c;从网盘下载ElasticSearch7.13.4 链接: https://pan.baidu.com/s/1vwUu1kbpCc5exkfOPgb29g 提取码: thn5 &#xff08;2&#xff09;方式二&#xff0c;从官网下载 https://www.elastic.co/cn/downloads/past-…

【C++学习】C++11——lambda表达式 | 可变参数模板 | 包装器

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; lambda表达式 | 可变参数模板 | 包装器 &#x1f3c0;lambda表达式&#x1f94e;lambda表达式语法&am…

汇编十一、汇编实现外部中断

1、实现目的 (1)实现8颗LED灯呈流水灯依次被点亮&#xff1b;静态数码管通过按键按下&#xff0c;显示数值发生改变&#xff0c;通过按键依次显示0-9。 (2)按键检测采用外部中断检测。 2、原理图及硬件连接 2.1、LED灯 (1)51单片机P1端口接八个共阴极LED灯&#xff0c;即I…