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

news2024/12/23 11:57:38

39. 组合总和

  • 刷题icon-default.png?t=N7T8https://leetcode.cn/problems/combination-sum/description/
  • 文章讲解icon-default.png?t=N7T8https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html
  • 视频讲解icon-default.png?t=N7T8https://www.bilibili.com/video/BV1KT4y1M7HJ/?vd_source=af4853e80f89e28094a5fe1e220d9062
  • 回溯树图示:

  • 题解:
class Solution {
    //与之前组合总和的问题的区别在于:
        //之前的问题限制了元素个数k,本题中却未限制单个集合中元素个数
        //且因为可以无限被选取,所以排除0,均为正整数
        //这就表明本题回溯树的高度的控制条件只有sum,高度不能确定
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        //存储最终的结果序列
        List<List<Integer>> result = new ArrayList<>();
        //为了进行合适的剪枝,需要对原始序列进行预排序
        Arrays.sort(candidates);
        combinationSum1(result, new ArrayList<>(), candidates, target, 0, 0);
        return result;
    }
    //参数1:传入最终结果列表
    //参数2:传入存储单个结果的列表
    //参数3:传入原始序列
    //参数4:传入目标总和
    //参数5:传入当前总和
    //参数6:传入控制for循环遍历的起始
    public void combinationSum1(List<List<Integer>> result, List<Integer> path, int[] candidates, int target, int sum, int startIndex){
        //递归出口,此时找到了和为target的组合,直接返回
        //由于元素可以无限选取,所以递归结束的情况只有两种:
            //1、总和恰好等于目标值,递归结束
            //2、总和大于目标值,递归结束
        if(sum == target){
            result.add(new ArrayList<>(path));
            return;
        }
        //递归回溯部分
        //横向遍历,回溯树宽度即为原序列长度
        for(int i = startIndex; i < candidates.length; i++){
            //剪枝,若当前sum再加上当前值大于目标值,则直接终止当前的遍历
            //因为原序列都是经过递增排序的,当前值已经大于目标值了,再接着遍历的话会更大于目标值
            //所以需要结束当前遍历,进入下一个上级结点的遍历
            if(sum + candidates[i] > target){
                break;
            }
            //若加上当前值小于目标值,则可将当前值加入path序列
            path.add(candidates[i]);
            //递归部分
            //因为二级递归不需要和一级递归避免重复,因为题目中某个元素可以重复使用不限制使用次数
            //所以二级递归和一级递归一样仍然以i开始
            combinationSum1(result, path, candidates, target, sum + candidates[i], i);
            //回溯部分
            //移除最后一个
            path.remove(path.size() - 1);
        }
    }
}

40.组合总和II

  • 刷题icon-default.png?t=N7T8https://leetcode.cn/problems/combination-sum-ii/description/
  • 文章讲解icon-default.png?t=N7T8https://programmercarl.com/0040.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CII.html
  • 视频讲解icon-default.png?t=N7T8https://www.bilibili.com/video/BV12V4y1V73A/?vd_source=af4853e80f89e28094a5fe1e220d9062
  • 回溯树图示:

  • 题解:
class Solution {
    //标记used数组去重法
    //记录最终结果
    List<List<Integer>> result = new ArrayList<>();
    //记录单趟结果
    LinkedList<Integer> path = new LinkedList<>();
    //标记当前元素当前分支是否使用过
    boolean[] used;
    //记录当前总和
    int sum = 0;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        //创建和原始序列等长的used标记序列
        used = new boolean[candidates.length];
        //为了将重复元素放在一起进行的排序操作
        Arrays.sort(candidates);
        combinationSum21(candidates, target, 0);
        return result;
    }
    //树枝去重和树层去重
    //树枝可以使用两个值相等的不同元素,树层则不可以(经分析)
    //所以我们需要通过used数组进行树层去重
    public void combinationSum21(int[] candidates, int target, int startIndex){
        //递归出口
        if(sum == target){
            result.add(new ArrayList<>(path));
            return;
        }
        //递归回溯部分
        for(int i = startIndex; i < candidates.length; i++){
            if(sum + candidates[i] > target){
                break;
            }
            //进行树层去重
            //debug点:防止 i-1 < 0 下标越界,需要再加限制条件i > 0
            if(i>=1 && candidates[i] == candidates[i - 1] && !used[i - 1]){
                //继续进行该层后序元素的遍历
                continue;
            }
            used[i] = true;
            sum += candidates[i];
            path.add(candidates[i]);
            //递归部分
            //因为题中要求candidates 中的每个数字在每个组合中只能使用一次,
            //则下次递归startIndex从i+1开始
            combinationSum21(candidates, target, i + 1);
            //回溯部分
            used[i] = false;
            sum -= candidates[i];
            path.removeLast();
        }
        
    }
}

131.分割回文串

  • 刷题icon-default.png?t=N7T8https://leetcode.cn/problems/palindrome-partitioning/description/
  • 文章讲解icon-default.png?t=N7T8https://programmercarl.com/0131.%E5%88%86%E5%89%B2%E5%9B%9E%E6%96%87%E4%B8%B2.html
  • 视频讲解icon-default.png?t=N7T8https://www.bilibili.com/video/BV1c54y1e7k6/?vd_source=af4853e80f89e28094a5fe1e220d9062
  • 回溯树图示:

  • 题解:
class Solution {
    //存放整体结果
    List<List<String>> result = new ArrayList<>();
    //存放单趟结果
    Deque<String> deque = new LinkedList<>();
    public List<List<String>> partition(String s) {
        partition1(s, 0);
        return result;
    }
    //关键点在于:
        //1、判断的合理区间在[startIndex, i]左闭右闭区间内
        //2、分割线即为每次递归或者回溯后的startIndex
    public void partition1(String s, int startIndex){
        //递归出口
        if(startIndex >= s.length()){
            result.add(new ArrayList(deque));
            return;
        }
        //递归回溯部分
        for(int i = startIndex; i < s.length(); i++){
            //若是回文子串,则记录结果
            if(isHuiwen(s, startIndex, i)){
                //因为substring左闭右开,而目标区间是左闭右闭,所以右边界加了1
                String str = s.substring(startIndex, i + 1);
                deque.addLast(str);
            }else{
                //若不是回文子串,则继续向后遍历即可
                continue;
            }
            //递归
            //因为需要保证不重复,则起始位置后移
            partition1(s, i + 1);
            //回溯
            deque.removeLast();
        }
    }
    //判断是否为回文子串
    public boolean isHuiwen(String s, int startIndex, int end){
        for(int i = startIndex, j = end; i < j; i++, j--){
            if(s.charAt(i) != s.charAt(j)){
                return false;
            }
        }
        return true;
    }
}

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

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

相关文章

【数据分享】2014-2024年全国监测站点的逐年空气质量数据(15个指标\免费获取)

空气质量的好坏反映了空气的污染程度&#xff0c;在各项涉及城市环境的研究中&#xff0c;空气质量都是一个十分重要的指标。空气质量是依据空气中污染物浓度的高低来判断的。 我们发现学者王晓磊在自己的主页里面分享了2014年5月以来的全国范围的到站点的逐时空气质量数据&am…

【Python笔记-设计模式】组合模式

一、说明 组合模式是一种结构型设计模式&#xff0c; 你可以使用它将对象组合成树状结构&#xff0c; 并且能像使用独立对象一样使用它们。 (一) 解决问题 处理树形结构&#xff1a;可以很好地处理树形结构的数据&#xff0c;使得用户可以统一对待单个对象和对象组合。统一接…

【LeetCode每日一题】 单调栈的案例 42. 接雨水

这道题是困难&#xff0c;但是可以使用单调栈&#xff0c;非常简洁通俗。 关于单调栈可以参考单调栈总结以及Leetcode案例解读与复盘 42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 …

2 物理层(五):传输介质

目录 1 传输介质1.1 有线传输媒体1、双绞线2、同轴电缆3、光纤 1.2 无线传输媒体1、无线电波段分配2、微波通信3、卫星通信4、红外通信和激光通信 1 传输介质 物理层传输的二进制比特流需要在传输介质上实现。传输介质是数据传输的物理通道&#xff0c;它还能连接主机和各种网…

【JAVA】中的静态代理、动态代理以及CGLIB动态代理

目录 1.静态代理 2.动态代理 3.cglib代理 代理模式是java中最常用的设计模式之一&#xff0c;尤其是在spring框架中广泛应用。对于java的代理模式&#xff0c;一般可分为&#xff1a;静态代理、动态代理、以及CGLIB实现动态代理。 对于上述三种代理模式&#xff0c;分别进行…

Kubernetes 二进制部署 《easzlab / kubeasz项目部署》(一)

Kubernetes 二进制部署 - easzlab / kubeasz项目部署 1. 准备工作1.1 设置防火墙1.2 设置SeLinux1.3 设置时区及时间同步1.4 配置域名解析1.5 确认SSH开启1.6 IP转发1.7 安装docker1.8 关闭swap 2. 服务器规划2.1 基本架构图2.2 官方建议2.3 实践服务器规划 3. 服务器配置3.1 配…

基于MPPT最大功率跟踪算法的涡轮机控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于MPPT最大功率跟踪算法的涡轮机控制系统simulink建模与仿真.mppt采用爬山法实现&#xff0c;仿真输出MPPT控制效果&#xff0c;功率&#xff0c;转速等。 2.系统仿真结果 …

SQL注入漏洞解析--less-2

首先我们进入第二关 思路&#xff1a; 1.先判断是什么类型的注入 2.根据类型我们在找注入点 步骤&#xff1a; 1.提示我们输入id数字&#xff0c;那我们先输入1猜一下 2.这里正常回显&#xff0c;当我们后边加上时可以看到报错&#xff0c;且报错信息看不到数字&#xff0…

Go 中如何高效遍历目录?探索几种方法

嗨&#xff0c;大家好&#xff01;我是波罗学。本文是系列文章 Go 技巧第十八篇&#xff0c;系列文章查看&#xff1a;Go 语言技巧。 目录遍历是一个很常见的操作&#xff0c;它的使用场景有如文件目录查看&#xff08;最典型的应用如 ls 命令&#xff09;、文件系统清理、日志…

知识积累(二):损失函数正则化与权重衰减

文章目录 1. 欧氏距离与L2范数1.1 常用的相似性度量 2. 什么是正则化&#xff1f;参考资料 本文只介绍 L2 正则化。 1. 欧氏距离与L2范数 欧氏距离也就是L2范数 1.1 常用的相似性度量 1&#xff09;点积 2&#xff09;余弦相似度 3&#xff09;L1和L2 2. 什么是正则化&…

游戏史上五个定价最高的量产型游戏机

你买过微软和索尼的下一代游戏机PS5和XBOX吗&#xff1f; PS5光驱版售价499美元&#xff0c;无光驱版售价399美元&#xff0c;高端版售价499美元&#xff0c;入门版售价低至299美元。 对于这样的定价&#xff0c;你觉得贵还是便宜呢&#xff1f; 为什么不让我们垂直比较整个游戏…

前端数据可视化:ECharts使用

可视化介绍 ​  ​  应对现在数据可视化的趋势&#xff0c;越来越多企业需要在很多场景(营销数据&#xff0c;生产数据&#xff0c;用户数据)下使用&#xff0c;可视化图表来展示体现数据&#xff0c;让数据更加直观&#xff0c;数据特点更加突出。   ​  数据可视化主要目…

【论文精读】IBOT

摘要 掩码语言建模(MLM)是一种流行的语言模型预训练范式&#xff0c;在nlp领域取得了巨大的成功。然而&#xff0c;它对视觉Transformer (ViT)的潜力尚未得到充分开发。为在视觉领域延续MLM的成功&#xff0c;故而探索掩码图像建模(MIM)&#xff0c;以训练更好的视觉transforme…

ico图片怎么制作(图片怎么变成ico格式)

ico图片一般命名为favicon.ico&#xff0c;主要用于作为缩略的网站标志&#xff0c;显示在浏览器的地址栏或者在标签中&#xff0c;一般用网站logo来制作。那么ico图片怎么制作&#xff1f;Logo图片怎么变成ico格式&#xff1f;下面boke112百科就跟大家说一说ico图片制作步骤&a…

【C++】——模板初阶 | STL简介

前言: 模板初阶 | STL简介 文章目录 一、模板初阶1.1 函数模板1.2 类模板 二、STL简介 &#xff08;了解&#xff09; 一、模板初阶 泛式编程&#xff08;Generic Programming&#xff09;指的是一种编程范式&#xff0c;其核心思想是编写可以在不同数据类型上通用的代码&#…

真的是性能优化(压测)-纯思想

文章目录 概要优化指标-MD都是文字看看就行性能优化操作1、代码优化&#xff1a;2、系统配置与环境优化&#xff1a;3、架构与设计&#xff1a;4、~~实施与监控&#xff1a;~~5、~~开发流程和环境管理&#xff1a;~~ 总结 概要 性能优化是一个持续的过程&#xff0c;需要监控、…

如何管理Windows Server磁盘分区?

Windows Server系统内置的分区软件有哪些&#xff1f; 系统内置的Windows Server分区管理软件主要分为两个——磁盘管理工具和Diskpart命令。其中磁盘管理工具可以帮助人们进行基础的磁盘、分区或卷管理任务&#xff0c;Diskpart命令则是在命令提示符中使用命令行来管理磁盘分…

如何将新标注的三元组数据转换成unicoqe可以处理的格式

目录 问题描述: 问题解决: 问题描述: 原始的标注的三元组格式如下: 需要转换的格式如下: tips:有一个小的难点: 1. 针对多三元组的情况,需要额外考虑 2. 最后一个样本,也记得需要处理

QEMU之CPU虚拟化

概述 KVM是由以色列初创公司Qumranet在CPU推出硬件虚拟化之后开发的一个基于内核的虚拟机监控器。 KVM是一个虚拟化的统称方案&#xff0c;除了x86外&#xff0c;ARM等其他架构也有自己的方案&#xff0c;所以KVM的主体代码位于内核树virt/kvm目录下面&#xff0c;表示所有CP…

JUC并发编程最新面试题(持续更新)

JUC并发编程 1 并发编程的优缺点为什么要使用并发编程&#xff08;并发编程的优点&#xff09; 充分利用多核CPU的计算能力&#xff1a;通过并发编程的形式可以将多核CPU 的计算能力发挥到极致&#xff0c;性能得到提升方便进行业务拆分&#xff0c;提升系统并发能力和性能&a…