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

39. 组合总和

在这里插入图片描述

题目链接:39. 组合总和
文档讲解:代码随想录
状态:卡了一会儿

思路:先排序,方便剪枝。允许数字重复使用,因此递归调用时传入当前索引i。

题解:

public class Solution {
    // 用于存储所有可能的组合
    private List<List<Integer>> res = new ArrayList<>();
    // 当前正在构建的组合
    private LinkedList<Integer> list = new LinkedList<>();
    // 用于存储当前组合的和
    private int sum = 0;

    /**
     * 组合求和函数
     * @param candidates 候选数字数组
     * @param target 目标数字
     * @return 所有可能的组合列表
     */
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        // 首先对候选数字进行排序
        Arrays.sort(candidates);
        // 调用回溯函数
        backtracking(candidates, target, 0);
        // 返回所有可能的组合
        return res;
    }

    /**
     * 回溯函数,用于递归地搜索所有可能的组合
     * @param candidates 候选数字数组
     * @param target 目标数字
     * @param startIndex 当前搜索的起始索引
     */
    public void backtracking(int[] candidates, int target, int startIndex) {
        // 如果当前和大于目标,则回溯
        if (sum > target) {
            return;
        }
        // 如果当前和等于目标,将当前组合添加到结果列表中
        if (sum == target) {
            res.add(new ArrayList<>(list));
            return;
        }
        // 遍历候选数字,从startIndex开始,直到sum+当前数字大于目标或遍历完所有数字
        for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {
            // 将当前数字添加到当前组合中,并更新当前和
            sum += candidates[i];
            list.add(candidates[i]);
            // 递归调用回溯函数,搜索当前数字之后的组合
            backtracking(candidates, target, i); // 注意这里传入i,允许重复使用同一个数字
            // 回溯,移除当前数字,恢复当前和
            sum -= candidates[i];
            list.removeLast();
        }
    }
}

40.组合总和II

在这里插入图片描述

题目链接:40.组合总和II
文档讲解:代码随想录
状态:自己在去重的时候,将集合中的重复元素也去掉了,导致结果缺少。集合(数组candidates)有重复元素,但还不能有重复的组合,这个不会处理。

思路:使用used数组标记树层或树枝中的元素是否使用,从而将集合有重复元素和结果又重复组合区分开。
默认used数组都为false,树层有重复元素和树枝有重复元素的关键区别在于used[i-1]是否为true,树层中元素因为回溯会使used[i-1]恢复成false,树枝中有重复元素则used[i-1]使用过,因此为true。在这里插入图片描述

题解:

    List<List<Integer>> res = new ArrayList<>();  // 结果集
    LinkedList<Integer> list = new LinkedList<>();  // 当前组合
    int sum = 0;  // 当前组合的和

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);  // 排序,方便后续处理
        boolean[] used = new boolean[candidates.length];  // 记录每个元素是否被使用过
        Arrays.fill(used, false);  // 初始化为未使用
        backtracking(candidates, used, target, 0);  // 开始回溯
        return res;  // 返回结果集
    }

    public void backtracking(int[] candidates, boolean[] used, int target, int startIndex) {
        if (sum == target) {  // 当前组合的和等于目标值
            res.add(new ArrayList<>(list));  // 将当前组合加入结果集
            return;
        }
        for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {
            if (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1]) {  // 去重
                continue;
            }
            sum += candidates[i];  // 做出选择,更新当前组合的和
            list.add(candidates[i]);  // 将当前元素加入当前组合
            used[i] = true;  // 标记当前元素已被使用
            backtracking(candidates, used, target, i + 1);  // 递归,处理下一个元素
            list.removeLast();  // 撤销选择,回溯到上一个状态
            used[i] = false;  // 标记当前元素未被使用
            sum -= candidates[i];  // 更新当前组合的和
        }
    }

131.分割回文串

在这里插入图片描述

题目链接:131.分割回文串
文档讲解:代码随想录
状态:不会,想到分割方法,代码没写出来!

代码没写出来的原因:

  1. 写成了 if (startIndex == chars.length) { res.add(new ArrayList<>(list)); return; }认为 startIndex == chars.length - 1 时将list添加到res中。实际上因为backtracking(chars, i + 1);的存在,res中添加list的操作都是在下次递归中完成的,而这时i+1就导致startIndex每次都比原来的大了1。
  2. 写成了new String(chars, startIndex, i),而实际上第三个参数是长度
    // 存储所有分割方案的列表
    List<List<String>> res = new ArrayList<>();
    // 当前正在构建的分割方案
    LinkedList<String> list = new LinkedList<>();

    /**
     * 将字符串分割成回文子串的方案
     * @param s 输入的字符串
     * @return 分割方案的列表
     */
    public List<List<String>> partition(String s) {
        // 将字符串转换为字符数组
        char[] chars = s.toCharArray();
        // 从索引0开始回溯
        backtracking(chars, 0);
        // 返回所有分割方案
        return res;
    }

    /**
     * 回溯函数,用于递归地搜索所有可能的回文子串分割方案
     * @param chars 字符串转换后的字符数组
     * @param startIndex 当前搜索的起始索引
     */
    public void backtracking(char[] chars, int startIndex) {
        // 如果当前索引等于字符数组的长度,说明已经处理完所有字符,将当前方案添加到结果中
        if (startIndex == chars.length) {
            res.add(new ArrayList<>(list));
            return;
        }
        // 从当前索引开始,尝试所有可能的分割点
        for (int i = startIndex; i < chars.length; i++) {
            // 如果从startIndex到i的子串是回文串,则将其添加到当前方案中
            if (isPalindrome(chars, startIndex, i)) {
                // 添加子串到当前方案
                list.add(new String(chars, startIndex, i - startIndex + 1));
                // 递归调用回溯函数,继续搜索i之后的分割方案
                backtracking(chars, i + 1);
                // 回溯,移除最后一个添加的子串,以便尝试其他分割方案
                list.removeLast();
            }
        }
    }

    /**
     * 判断子串是否为回文串
     * @param chars 字符数组
     * @param start 子串的起始索引
     * @param end 子串的结束索引
     * @return 如果子串是回文串返回true,否则返回false
     */
    public boolean isPalindrome(char[] chars, int start, int end) {
        // 从子串的两端向中间遍历,如果字符不相等则不是回文串
        while (start <= end) {
            if (chars[start] != chars[end]) {
                return false;
            }
            start++;
            end--;
        }
        // 如果遍历完所有字符都相等,则子串是回文串
        return true;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vivado NODE、PACKAGE_PIN

节点是Xilinx部件上用于路由连接或网络的设备对象。它是一个 WIRE集合&#xff0c;跨越多个瓦片&#xff0c;物理和电气 连接在一起。节点可以连接到单个SITE_&#xff0c; 而是简单地将NETs携带进、携带出或携带穿过站点。节点可以连接到 任何数量的PIP&#xff0c;并且也可以…

Science | 稀土开采威胁马来西亚的生物多样性

马来西亚是一个生物多样性热点地区&#xff0c;拥有超过17万种物种&#xff0c;其中1600多种处于濒临灭绝的风险。马来西亚的热带雨林蕴藏了大部分的生物多样性&#xff0c;并为全球提供重要的生态系统效益&#xff0c;同时为土著社区带来经济和文化价值。同时马来西亚具有可观…

nginx安装环境部署(完整步骤)

在部署nginx前&#xff0c;我们需要进行环境的部署 1.编译工具gcc&#xff0c;g,autoconf&#xff0c;automake &#xff0c;make sudo apt-get install gcc g autoconf automake make 2.依赖库zlib&#xff0c;openssl&#xff0c;pcre 2.1 openssl下载地址 https://www.open…

韩兴国/姜勇团队在《Trends in Plant Science》发表植物根系氮素再分配的观点文章!

氮素是陆地生态系统中的关键限制性营养元素&#xff0c;通过生物固氮和土壤氮供应通常远低高等植物的氮需求。当土壤氮素供应无法充分满足植物茎叶生长需求时&#xff0c;植物会通过自身营养器官&#xff08;如根或根茎&#xff09;再分配来实现氮的内部循环和再利用。尽管植物…

首批50辆苏州金龙纯电大巴交付!武汉通勤客运绿色发展提质升级

随着第一缕阳光跃上黄鹤楼的飞檐&#xff0c;城市逐渐苏醒。在车水马龙中&#xff0c;一辆辆通勤班车穿梭其中&#xff0c;确保通勤保障单位人员的安全出行。而这其中就有武汉市雄翔通勤汽车运输有限公司&#xff08;以下简称“武汉雄翔”&#xff09;的身影。 5月底&#xff…

Postman 请求参数传递指南:Query、Path和Body

Postman 作为一个功能强大的工具&#xff0c;极大地简化了 API 测试和调试的过程&#xff0c;提供了发送请求和检查响应的直接方法。本文将着重介绍如何在 Postman 中高效地处理请求参数&#xff0c;以提高 API 测试和开发的便利性。 1、解析请求参数 首先&#xff0c;我们需要…

11.5.k8s中pod的调度-cordon,drain,delete

目录 一、概念 二、使用 1.cordon 停止调度 1.1.停止调度 1.2.解除恢复 2.drain 驱逐节点 2.1.驱逐节点 2.2.参数介绍 2.3.解除恢复 3.delete 删除节点 一、概念 cordon节点&#xff0c;drain驱逐节点&#xff0c;delete 节点&#xff0c;在对k8s集群节点执行维护&am…

深度学习训练——batch_size参数设置过大反而训练更耗时的原因分析

&#x1f4aa; 专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &#x1f4dd;《暗光增强》 &a…

重学java 71.网络编程

人生不是坐等暴风雨过去&#xff0c;而是学会在雨中起舞 —— 24.6.14 一、网络编程的基础概念 1.概述&#xff1a; 在网络通信协议下,不同计算机上运行的程序,进行数据传输 比如&#xff1a;通信、视频通话、网络、邮件 只要是计算机之间通过网络进行数据传输&#xff0c;就有…

想上币的项目方怎么去选择交易所

在区块链和加密货币蓬勃发展的今天&#xff0c;许多项目方都渴望通过交易所上线其代币&#xff0c;以扩大影响力、提升流动性和市场认可度。然而&#xff0c;选择合适的交易所并非易事&#xff0c;它关乎项目的未来发展和市场地位。那么&#xff0c;对于有上币意向的项目来说&a…

Maya 2024 mac/win版:创意无界,设计新生

Maya 2024是一款由Autodesk推出的业界领先的三维计算机图形软件&#xff0c;广泛应用于电影、游戏、广告等创意产业。这款软件以其强大的功能和卓越的性能&#xff0c;为艺术家们提供了一个实现创意梦想的平台。 Maya 2024 mac/win版获取 在建模方面&#xff0c;Maya 2024提供…

arsetryhtehrwgefwadasdadasd

48b91400000080f7ffff48b8bd427ae5d594bfd6488b0948f7e148b8cdcccccccccccccc48c1ea1748f7e24c8bea49c1ed02 直接在windbg中把执行内存修改为上面这一串字节序列&#xff0c;运行完成后r13中将包含当前时间戳&#xff0c;可使用如下代码转换成人类可阅读时间格式 /*代码BEGIN*…

服务器----阿里云服务器重启或关机,远程连接进不去,个人博客无法打开

问题描述 在使用阿里云免费的新加坡服务器时&#xff0c;发现重启或者是关机在开服务器后&#xff0c;就会出现远程连接不上、个人博客访问不了等问题 解决方法 进入救援模式连接主机&#xff0c;用户名是root&#xff0c;密码是自己设置的 点击访问博客查看更多内容

003 gitee怎样将默认的私有仓库变成公开仓库

先点击“管理”&#xff0c; 再点击“基本信息” 在“是否开源”里&#xff0c; 选择&#xff1a;开源

如何设置天锐绿盾的数据防泄密系统

设置天锐绿盾的数据防泄密系统&#xff0c;可以按照以下步骤进行&#xff1a; 一、系统安装与初始化 在线或离线安装天锐绿盾数据防泄密系统&#xff0c;确保以管理员身份运行安装包&#xff0c;并按照安装向导的提示完成安装。输入序列号进行注册&#xff0c;激活系统。 二…

代码解读 | Hybrid Transformers for Music Source Separation[07]

一、背景 0、Hybrid Transformer 论文解读 1、代码复现|Demucs Music Source Separation_demucs架构原理-CSDN博客 2、Hybrid Transformer 各个模块对应的代码具体在工程的哪个地方 3、Hybrid Transformer 各个模块的底层到底是个啥&#xff08;初步感受&#xff09;&#xff1…

Linux自旋锁

面对没有获取锁的现场&#xff0c;通常有两种处理方式。 互斥锁&#xff1a;堵塞自己&#xff0c;等待重新调度请求自旋锁&#xff1a;循环等待该锁是否已经释放 本文主要讲述自旋锁 自旋锁其实是一种很乐观的锁&#xff0c;他认为只要再等一下下锁便能释放&#xff0c;避免…

Golang内存模型与分配机制

简述 mheap为堆&#xff0c;堆和进程是一对一的&#xff1b;mcentral&#xff08;小mheadp&#xff09;&#xff0c;mcahe&#xff08;GMP的P私有&#xff09;&#xff0c;分配内存顺序由后向前。 在解决这个问题&#xff0c;Golang 在堆 mheap 之上&#xff0c;依次细化粒度&a…

【UML用户指南】-17-对基本行为建模-交互

目录 1、消息的可视化表示 2、对象与角色 3、链和连接件 4、消息 5、序列 6、创建、修改和撤销 7、表示法 8、常用建模技术 8.1、对控制流建模 8.1.1、基于时间的控制流 8.1.2、基于结构的控制流 在任何有意义的系统中&#xff0c;对象都不是孤立存在的&#xff0c;…

4.类,方法,对象

1.1.2. 面向对象程序设计的三大特征 1.1.2.1. 封装 面向对象编程核心思想之一就是将数据和对数据的操作封装在一起&#xff0c;形成一般的概念&#xff0c;比如类的概念。 1.1.2.2. 继承 继承体现了一种先进的编程模式。子类可以继承父类的属性和方法。 1.1.2.3. 多态 多…