代码随想录算法训练营day27 | 39. 组合总和,40. 组合总和 II,131. 分割回文串

目录

39. 组合总和

40. 组合总和 II

131. 分割回文串


39. 组合总和

难度:medium

类型:回溯

 

思路:

        这道题的特点是,组合没有元素个数要求,数组无重复元素,每个元素可以无限选取。

        组合没有元素个数要求:不需要通过path长度判断来跳出递归,通过sum来跳出;

        数组无重复元素:不需要进行去重操作

        每个元素可以无限选取:每次进行下层递归时,startIndex为i,不是i+1

39.组合总和1

        先给数组排序,是为了后续的剪枝操作;

代码:

class Solution {private List<Integer> path = new ArrayList<>();private List<List<Integer>> ans = new ArrayList<>();private int sum = 0;public List<List<Integer>> combinationSum(int[] candidates, int target) {     if (candidates.length == 0) {return ans;} // 排序Arrays.sort(candidates);backtracking(candidates, target, 0);return ans;}public void backtracking(int[] candidates, int target, int startIndex) {// if (sum > target) {//     return;// }if (sum == target) {ans.add(new ArrayList<>(path));return;}// 剪枝操作:sum + candidates[i] <= target,若超过target,不需要进入下一层递归判断for (int i = startIndex; i < candidates.length; i++) {if (sum + candidates[i] > target) {break;}sum += candidates[i];path.add(candidates[i]);backtracking(candidates, target, i);sum -= candidates[i];path.remove(path.size() - 1);}}}
  • 时间复杂度: O(n * 2^n),注意这只是复杂度的上界,因为剪枝的存在,真实的时间复杂度远小于此
  • 空间复杂度: O(target)

40. 组合总和 II

难度:medium

类型:回溯

 

思路:

        本题的特点是:集合中有重复元素,集合每个元素在每个组合只能使用一次;

集合中有重复元素:进行去重操作;避免递归树中同一层有重复元素,同一层的元素会出现在path的相同位置,会造成重复的组合(去重前先要排序)

        1.使用startIndex方法去重

        i>0无法确定candidates[i]和candidates[i - 1]是同层还是同枝;而i>startIndex可以确定是同层;

            if (i > startIndex && candidates[i] == candidates[i - 1]) {continue;

        2.使用used数组去重

           if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {continue;}

·        在candidates[i] == candidates[i - 1]相同的情况下:

  • used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
  • used[i - 1] == false,说明同一树层candidates[i - 1]使用过

40.组合总和II1

      

集合每个元素在每个组合只能使用一次:调用递归时,startIndex为i+1

代码:

class Solution {private List<List<Integer>> ans = new ArrayList<>();private List<Integer> path = new ArrayList<>();private int sum = 0;public List<List<Integer>> combinationSum2(int[] candidates, int target) {if (candidates.length == 0) {return ans;}Arrays.sort(candidates);backtracking(candidates, target, 0);return ans;}public void backtracking(int[] candidates, int target, int startIndex) {if (sum == target) {ans.add(new ArrayList<>(path));return;}for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {// 避免递归树中同一层有重复元素,同一层的元素会出现在path的相同位置,会造成重复的组合// 例如candidates = [1,2,2,2,2,3,3,3,3],target = 6if (i > startIndex && candidates[i] == candidates[i - 1]) {continue;}sum += candidates[i];path.add(candidates[i]);backtracking(candidates, target, i + 1);sum -= candidates[i];path.remove(path.size() - 1);}}
}// 使用used数组方法
class Solution {private List<List<Integer>> ans = new ArrayList<>();private List<Integer> path = new ArrayList<>();private boolean[] used;// used[i - 1] == true,说明同一树枝candidates[i - 1]使用过// used[i - 1] == false,说明同一树层candidates[i - 1]使用过private int sum = 0;public List<List<Integer>> combinationSum2(int[] candidates, int target) {if (candidates.length == 0) {return ans;}Arrays.sort(candidates);used = new boolean[candidates.length];backtracking(candidates, target, 0);return ans;}public void backtracking(int[] candidates, int target, int startIndex) {if (sum == target) {ans.add(new ArrayList<>(path));return;}for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {// 这里是关键区别,除了对used[i-1]判定外,i>0也不同于上面的i>startIndex// 因为i>0无法确定candidates[i]和candidates[i - 1]是同层还是同枝;而i>startIndex可以确定是同层if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {continue;}sum += candidates[i];path.add(candidates[i]);used[i] = true;backtracking(candidates, target, i + 1);sum -= candidates[i];path.remove(path.size() - 1);used[i] = false;}}
}
  • 时间复杂度: O(n * 2^n)
  • 空间复杂度: O(n)

 

131. 分割回文串

难度:medium

类型:回溯

 

思路:

        本题为切割问题,也是组合的一种。

131.分割回文串131.分割回文串

 

代码:

class Solution {private List<List<String>> ans = new ArrayList<>();private List<String> path = new ArrayList<>();public List<List<String>> partition(String s) {backtracking(s, 0);return ans;}public void backtracking(String s, int startIndex) {if (startIndex == s.length()) {ans.add(new ArrayList<>(path));return;}for (int i = startIndex; i < s.length(); i++) {// substring()方法为左闭右开String str = s.substring(startIndex, i + 1);if (judge(str)) {path.add(str);backtracking(s, i + 1);path.remove(path.size() - 1);}}}public boolean judge(String s) {int left = 0; int right = s.length() - 1;while (left < right) {if (s.charAt(left) != s.charAt(right)) {return false;}left++;right--;}return true;}
}
  • 时间复杂度: O(n * 2^n)
  • 空间复杂度: O(n^2)

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

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

相关文章

【Mysql】数据库基础与基本操作

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

HttpRunner搭建接口自动化测试项目

前言&#xff1a;前面写过一篇PytestAllure接口自动化测试框架搭建的博客&#xff0c;这篇博客学习另外一款优秀的开源的接口自动化测试框架&#xff1a;HttpRunner&#xff0c;本博客主要学习如何搭建基于HttpRunner的接口自动化测试项目 PytestAllure接口自动化测试框架搭建…

uniapp实现自定义导航内容高度居中(兼容APP端以及小程序端与胶囊对齐)

①效果图如下 1.小程序端与胶囊对齐 2.APP端内容区域居中 注意&#xff1a;上面使用的是colorui里面的自定义导航样式。 ②思路&#xff1a; 1.APP端和小程序端走不同的方法&#xff0c;因为小程序端要计算不同屏幕下右侧胶囊的高度。 2.其次最重要的要清晰App端和小程序端…

这50幅画让你看清世界真相,犀利深刻,值得一读!

让你看清这个世界的真相&#xff01; 01 自弃者扶不起 自强者打不倒 02 人人都活在假象里 03 宁可有病再治&#xff0c;也不愿意未雨绸缪 04 一个人成熟的表现 是具备了太极思维 05 最大的监狱是人的思维监狱 06 认知太浅&#xff0c;放弃学习 这就是焦虑和绝望的根本原因 0…

GPT-4助力数据分析:提升效率与洞察力的未来关键技术 | 京东云技术团队

摘要 随着大数据时代的到来&#xff0c;数据分析已经成为企业和组织的核心竞争力。然而&#xff0c;传统的数据分析方法往往无法满足日益增长的数据分析需求的数量和复杂性。在这种背景下&#xff0c;ChatGPT-4作为一种先进的自然语言处理技术&#xff0c;为数据分析带来了革命…

DevExpress WinForms Gantt组件——轻松可视化项目时间表内的时间轴

DevExpress WinForms的Gantt组件在v23.1中附带了一个新的时间轴UI元素&#xff0c;Gantt&#xff08;甘特图&#xff09;控件本身允许您计划/管理项目&#xff0c;而时间轴显示单个任务的开始和截止日期&#xff0c;并提供项目进度的鸟瞰图。 DevExpress WinForms 拥有180组件和…

如何使用Audition生成固定频率的正弦波

一&#xff0c;简介 本文主要介绍如何使用Audition软件生成固定频率的正弦波进行相关测试验证工作。 二&#xff0c;准备工作 需要安装Audition软件&#xff0c;本次使用的是Adobe Audition CC 2018绿色版。其他版本也都可以&#xff0c;只是步骤上可能有细微的差别。 三&…

GDB 打印uint64位数据值

今天一来组长就让我查一个问题&#xff0c;说是我们的接口返回的数据需要赋值为-1&#xff0c;返回给上层调用。结果我一看代码&#xff0c;代码里就是写死了赋值 -1 的&#xff0c;但他说实际返回的好像不是 -1&#xff0c;所以只能让我gdb 跟踪一下了。本来想用 window 下的计…

享元模式 Flyweight Pattern 《游戏编程模式》学习笔记

如果我们要存储一个树一样的数据结构&#xff0c;直觉来说我们会这么写 但是实际上我们会发现&#xff0c;哪怕森林里有千千万万的树&#xff0c;它们大多数长得一模一样。 它们使用了相同的网格和纹理。 这意味着这些树的实例的大部分字段是一样的。 那么我们就可以将树共…

适配器模式来啦

网上的大多数的资料中适配器模式和代理模式都是紧挨着进行介绍的&#xff0c;为什么呢&#xff1f;&#xff1f;&#xff1f; 是因为适配器模式和代理模式有太多的相似之处&#xff0c;可以进行联动记忆但是也要做好区分。 在菜鸟教程中&#xff0c;适配器模式的定义是作为两…

linux环形缓冲区kfifo实践1

本次实验使用的kfifo相关宏 struct __kfifo {unsigned int in;unsigned int out;unsigned int mask;unsigned int esize;void *data;}; /** define compatibility "struct kfifo" for dynamic allocated fifos*/ struct kfifo __STRUCT_KFIFO_PTR(unsigned char, …

安全杂记 - 复现nodejs沙箱绕过

目录 一. 配置环境1.下载nodejs2.nodejs配置3.报错解决方法 二. nodej沙箱绕过1. vm模块2.使用this或引用类型来进行沙箱绕过 一. 配置环境 1.下载nodejs 官网&#xff1a;https://nodejs.org/en2.nodejs配置 安装nodejs的msi文件&#xff0c;默认配置一直下一步即可&#x…