Day 27 回溯法 LeedCode: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 。
仅有这两种组合。

思路:本题和Day25:回溯法 LeedCode216.组合总和III 17.电话号码的字母组合-CSDN博客思路类似,区别在于本题的数可以重复取,可以通过控制递归的参数来实现

递归三部曲:

1.确定返回值和参数类型:

定义两个全局变量

List<List<Integer>> result存储结果

List<Integer> path存储符合条件的组合

定义int型的sum变量来统计单一结果path里的总和

传入集合candidates, 目标值target,和sum。

返回void

2.确定递归结束条件:

如果当前和大于等于目标和,则递归结束

 if(sum==target){
        result.add(new ArrayList(path));
        return;
     }
     if(sum>target){
        return;
     }

3.确定单层逻辑:

for循环遍历本层可以取的数,Index来控制for循环的起始位置

     for(int i=index;i<candidates.length;i++){
        path.add(candidates[i]);
        //因为可以重复,index还是为i
        backTracking(candidates,target,i,sum+candidates[i]);//回溯
        path.removeLast();
     }

代码参考:

class Solution {
List<List<Integer>> result; 
List<Integer> path;public List<List<Integer>> combinationSum(int[] candidates, int target) {result=new ArrayList<>();path=new LinkedList<Integer>();backTracking(candidates,target,0,0);return result;}void backTracking(int[]candidates,int target,int index,int sum){if(sum==target){result.add(new ArrayList(path));return;}if(sum>target){return;}for(int i=index;i<candidates.length;i++){path.add(candidates[i]);//因为可以重复,index还是为ibackTracking(candidates,target,i,sum+candidates[i]);//回溯path.removeLast();}}}

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]
]

思路:本题与上题相比,每个数要求只能使用一次而且数组candidates的元素是有重复的,要求结果是无重复的,所以我们要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重

代码参考:

class Solution {List<List<Integer>> result;List<Integer> path;public List<List<Integer>> combinationSum2(int[] candidates, int target) {result=new ArrayList<>();path=new LinkedList<>();//对数组排序,方便排除重复元素Arrays.sort(candidates);backTracking(candidates,target,0,0);return result;}void backTracking(int[] candidates,int target,int sum,int startIndex){if(sum==target){result.add(new ArrayList<>(path));return;}for(int i=startIndex;i<candidates.length&&sum+candidates[i]<=target;i++){正确剔除重复解的办法//跳过同一树层使用过的元素if ( i > startIndex && candidates[i] == candidates[i - 1] ) {continue;}path.add(candidates[i]);backTracking(candidates,target,sum+candidates[i],i+1);path.removeLast();}}
}

131. 分割回文串

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

回文串

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

示例 1:

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

示例 2:

输入:s = "a"
输出:[["a"]]提示:
  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成

 思路:用回溯法解决分割问题,遍历所有分割方式,将子字符串都是回文串的分割加入结果集

回文串是向前和向后读都相同的字符串,

本题这涉及到两个关键问题:

1.切割问题,有不同的切割方式

通过回溯的递归传入参数startIndex控制递归

2.判断回文

 }
    boolean isPalindrome(String s,int start,int end){
     for(int i=start,j=end;i<j;i++,j--){
        if(s.charAt(i)!=s.charAt(j))
        return false;
     }
     return true;
    }

本题如何切割:

 代码参考:

class Solution {List<List<String>> result=new ArrayList<>();List<String> path=new LinkedList();public List<List<String>> partition(String s) {backtracking(s,0);return result;}void  backtracking(String s,int startIndex){if(startIndex==s.length()){//每次分割的子字符串都是回文串result.add(new ArrayList(path));return;}for(int i=startIndex;i<s.length();i++){if(isPalindrome(s,startIndex,i)){path.add(s.substring(startIndex,i+1));}else{continue;}//当前分割的子字符串是回文串,指针后移,继续分割backtracking(s,i+1);path.removeLast();}}boolean isPalindrome(String s,int start,int end){for(int i=start,j=end;i<j;i++,j--){if(s.charAt(i)!=s.charAt(j))return false;}return true;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Node.js从基础到高级运用】二十、Node.js 强大的REPL

引言 Node.js REPL&#xff08;Read-Eval-Print Loop&#xff09;是一种交互式的命令行工具&#xff0c;它允许开发者快速地执行JavaScript代码&#xff0c;并查看结果。这个功能在进行快速原型设计、调试、学习JavaScript或Node.js时非常有用。 启动REPL 首先&#xff0c;确保…

Bitmap 用 matrix 旋转空白处变黑色

Matrix matrix new Matrix(); matrix.setRotate(degree, bitmap.getWidth() / 2, bitmap.getHeight() / 2); bitmap Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); Bitmap 用matrix 旋转出黑边_bitmap matrix.postrotate 有黑色…

大型企业通常如何进行单元测试?

你平时是怎么做单元测试的&#xff1f; 面试官心理预期 面试官询问单元测试并非仅仅想了解这一概念&#xff0c;背后可能考察面试者以下三个方面&#xff1a; 对软件工程生命周期的熟悉程度&#xff0c;以及对测试阶段各种方法&#xff08;包括单元测试、集成测试、冒烟测试等&…

ZFG92 7RM8010有功功率监视装置 AC380V 5A JOSEF约瑟

系列型号 ZFG92有功功率监视装置&#xff1b;ZFG93有功功率监视装置&#xff1b; ZFG92.93(SRG) 7RM8001有功功率监视装置&#xff1b;ZFG92.93(SRG) 7RM8010有功功率监视装置; ZFG92.93(SRG) 7RM8011有功功率监视装置&#xff1b;ZFG92.93(SRG) 7RM8012有功功率监视装置; ZFG9…

Shopee,lazada如何实施稳定的测评,补单自养号方案,关键的步骤和条件

随着平台竞争激烈&#xff0c;越来越多的商家对常规运营也是力不从心。传统的广告和营销方式已经无法满足商家的需求&#xff0c;因此自养号测评也成为商家重要的推广方式。实现自养号测评&#xff0c;补单所需的技术条件。 1.不同账户的独立运行环境和阻断平台检测非常重要。稳…

全网最全!仓库管理遇到难题!该怎么解决?

全网最全&#xff01;仓库管理遇到难题&#xff01;该怎么解决&#xff1f; 常见的仓库管理问题有哪些&#xff1f;在仓库管理系统中&#xff0c;如何实现库存校验&#xff1f;在仓库管理系统中&#xff0c;如何实现实时库存?在仓库管理系统中&#xff0c;如何实现库存预警&a…

【干货】零售企业商品数字化管理措施探讨

随着信息技术的迅猛发展、市场竞争的加剧以及消费者需求的多样化&#xff0c;鞋服品牌商品数字化管理的重要性愈发凸显。数字化管理不仅关乎企业运营效率的提升&#xff0c;更是品牌实现差异化竞争、提升顾客体验、构建智慧零售生态的关键所在。对于零售企业而言&#xff0c;提…

C++教学——从入门到精通 5.单精度实数float

众所周知&#xff0c;三角形的面积公式是(底*高)/2 那就来做个三角形面积计算器吧 到吗如下 #include"bits/stdc.h" using namespace std; int main(){int a,b;cin>>a>>b;cout<<(a*b)/2; } 这不对呀&#xff0c;明明是7.5而他却是7&#xff0c;…

什么是ISP住宅IP?相比于普通IP它的优势是什么?

什么是ISP住宅IP&#xff1f; ISP住宅IP是指由互联网服务提供商&#xff08;ISP&#xff09;分配给住宅用户的IP地址。它是用户在家庭网络环境中连接互联网的标识符&#xff0c;通常用于上网浏览、数据传输等活动。ISP住宅IP可以是动态分配的&#xff0c;即每次连接时都可能会…

Oracle基础【2-Oracle体系结构、存储结构与各类参数】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;Oracle从基础到进阶 本文对应Oracle实验报告源文件下载&#xff1a;公众号程序员刘同学回复oracle实验获取下载链接 体系结构、存储结构与各类参数一、实验目的二、实验环境三、实验内容1…

java线程(一)--进程,多线程,synchronized和lock锁,JUC,JUnit

Java线程入门 单核CPU和多核CPU的理解 单核CPU&#xff0c;其实是一种假的多线程&#xff0c;因为在一个时间单元内&#xff0c;也只能执行一个线程的任务。例如&#xff1a;虽然有多车道&#xff0c;但是收费站只有一个工作人员在收费&#xff0c;只有收了费才能通过&#xf…

网络安全入门教程(非常详细)从零基础入门到精通!

网络安全是一个庞大而不断发展的领域&#xff0c;它包含多个专业领域&#xff0c;如网络防御、网络攻击、数据加密等。介绍网络安全的基本概念、技术和工具&#xff0c;逐步深入&#xff0c;帮助您成为一名合格的网络安全从业人员。 一、网络安全基础知识 1.计算机基础知识 …