代码随想录算法训练营 Day27 回溯算法3

39. 组合总和

思路

根据题意画二叉树
这道题与之前的组合总和的区别在于,数组中的数字可以多次使用,因此每次递归时的startIndex依旧是从当前的i开始

尝试写代码:

class Solution:def __init__(self):self.path = []self.result = []def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:self.backtracking(candidates, target, 0, 0)return self.resultdef backtracking(self, candidates, target, startIndex, sum):if sum == target:self.result.append(self.path[:])return if sum > target:returnfor i in range(startIndex, len(candidates)):sum += candidates[i]self.path.append(candidates[i])self.backtracking(candidates, target, i, sum)sum -= candidates[i]self.path.pop()

成功通过

根据代码随想录
可以剪枝,先对数组排序,然后在for循环中一开始,先判断当前sum + 当前值是否大于目标值,如果是,就continue

最终代码:

class Solution:def __init__(self):self.path = []self.result = []def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:candidates.sort()self.backtracking(candidates, target, 0, 0)return self.resultdef backtracking(self, candidates, target, startIndex, sum):if sum == target:self.result.append(self.path[:])return for i in range(startIndex, len(candidates)):if sum + candidates[i] > target:continuesum += candidates[i]self.path.append(candidates[i])self.backtracking(candidates, target, i, sum)sum -= candidates[i]self.path.pop()

40. 组合总和 II

思路

由于给定的数组中包含重复元素,最终结果可能出现重复的组合,因此需要对最终结果进行去重
在python中,每次得到的组合加入result之前,先判断下result中是否有该组合

尝试写代码:

class Solution:def __init__(self):self.path = []self.result = []def backtracking(self, candidates, target, startIndex, sum):if sum == target:if self.path not in self.result:self.result.append(self.path[:])returnif sum > target:return for i in range(startIndex, len(candidates)):sum += candidates[i]self.path.append(candidates[i])self.backtracking(candidates, target, i + 1, sum)sum -= candidates[i]self.path.pop()def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:self.backtracking(candidates, target, 0, 0)return self.result

结果不对,去重失败,因为每个组合的排列顺序不一样,无法通过简单的in来判断。

换一种思路,先排序,如果i + 1 == i,在这里进行去重
尝试写代码

class Solution:def __init__(self):self.path = []self.result = []def backtracking(self, candidates, target, startIndex, sum):if sum == target:if self.path not in self.result:self.result.append(self.path[:])returnfor i in range(startIndex, len(candidates)):if sum + candidates[i] > target:continueif i - 1 and i - 1 == i:continuesum += candidates[i]self.path.append(candidates[i])self.backtracking(candidates, target, i + 1, sum)sum -= candidates[i]self.path.pop()def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:candidates.sort()self.backtracking(candidates, target, 0, 0)return self.result

测试用例通过,但总体超出时间限制

根据代码随想录
注意:

  1. 剪枝,在for循环内先判断,如果sum与当前值的和大于目标值,break
  2. 去重,如果当前值与上一个值相等,continue
  3. 去重时有两种方法,一是i > startIndex;一是使用used

最终代码,使用i > startIndex

class Solution:def __init__(self):self.path = []self.result = []def backtracking(self, candidates, target, startIndex, sum):if sum == target:self.result.append(self.path[:])returnfor i in range(startIndex, len(candidates)):if i > startIndex and candidates[i - 1] == candidates[i]:continueif sum + candidates[i] > target:breaksum += candidates[i]self.path.append(candidates[i])self.backtracking(candidates, target, i + 1, sum)sum -= candidates[i]self.path.pop()def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:candidates.sort()self.backtracking(candidates, target, 0, 0)return self.result

使用used

class Solution:def __init__(self):self.path = []self.result = []def backtracking(self, candidates, target, startIndex, sum, used):if sum == target:self.result.append(self.path[:])returnfor i in range(startIndex, len(candidates)):if i > 0 and candidates[i - 1] == candidates[i] and not used[i - 1]:continueif sum + candidates[i] > target:breaksum += candidates[i]self.path.append(candidates[i])used[i] = Trueself.backtracking(candidates, target, i + 1, sum, used)sum -= candidates[i]self.path.pop()used[i] = Falsedef combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:used = [False] * len(candidates)candidates.sort()self.backtracking(candidates, target, 0, 0, used)return self.result

总结
整体思路正确,但是具体写代码的去重逻辑时,有错误

131. 分割回文串

思路

画出树形结构图
不知道分割在递归代码中怎么写

根据代码随想录
分割问题和组合问题非常像

要点:

  1. 切割线可以用startIndex表示,即终止条件是当startIndex == len(s)
  2. 判断回文的逻辑放在单层递归中
  3. 如何表示切割的子串:可以用[startIndex, i]表示切割的子串

最终代码:

class Solution:def __init__(self):self.path = []self.result = []def isHui(self, string, start, end):while start < end:if string[start] != string[end]:return Falsestart += 1end -= 1return Truedef partition(self, s: str) -> List[List[str]]:self.backtracking(s, 0)return self.resultdef backtracking(self, s, startIndex):if startIndex == len(s):self.result.append(self.path[:])returnfor i in range(startIndex, len(s)):if self.isHui(s, startIndex, i):self.path.append(s[startIndex:i + 1])else:continueself.backtracking(s, i + 1)self.path.pop()

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

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

相关文章

Java练习题目3:输入一个学生的5门课成绩及对应的学分,计算该同学的加权平均分(WeightedAverageScore3)

每日小语 我们没有意识到惯用语言的结构有多大的力量。可以说&#xff0c;它通过语义反应机制奴役我们。 ——阿尔弗雷德科日布斯基 思考 输入5门课成绩&#xff0c;学分&#xff0c;加权平均分公式 [&#xff08;课程A成绩*课程A学分&#xff09;&#xff08;课程成绩B*课程…

Mybatis-Plus实现乐观锁

1 悲观锁和乐观锁场景和介绍 乐观锁和悲观锁是在并发编程中用于处理并发访问和资源竞争的两种不同的锁机制!! 1.1 悲观锁&#xff1a; 悲观锁的基本思想是&#xff0c;在整个数据访问过程中&#xff0c;将共享资源锁定&#xff0c;以确保其他线程或进程不能同时访问和修改该…

Learn OpenGL 19 几何着色器

几何着色器 在顶点和片段着色器之间有一个可选的几何着色器(Geometry Shader)&#xff0c;几何着色器的输入是一个图元&#xff08;如点或三角形&#xff09;的一组顶点。几何着色器可以在顶点发送到下一着色器阶段之前对它们随意变换。然而&#xff0c;几何着色器最有趣的地方…

动态路由协议——OSPF

目录 一.OSPF来源 二.OSPF术语 1.area id——区域的划分 2.cost——路径开销值 3.route id 4.LSDB表 5.邻居表 6.OSPF路由表 三.OSPF工作过程 1.交互hello报文建立邻居关系 2.选举主从 3.交互LSDB摘要信息 4.LSR,LSU,LSACK同步LSDB表项 5.各自计算路由 四.OSPF交…

简单函数_学分绩点

任务描述 北京大学对本科生的成绩施行平均学分绩点制&#xff08;GPA&#xff09;。既将学生的实际考分根据不同的学科的不同学分按一定的公式进行计算。 公式如下&#xff1a; 实际成绩 绩点 90——100 4.0 85——89 3.7 82——84 3.3 78——81 3.0 75——77 …

redis【面试题】

目录 Java全技术栈面试题合集地址Redis篇1.Redis 的数据类型&#xff1f;2.Redis 是单进程单线程的&#xff1f;3.一个字符串类型的值能存储最大容量是多少&#xff1f;4.Redis 的持久化机制是什么&#xff1f;各自的优缺点&#xff1f;5.redis 过期键的删除策略&#xff1f;6.…

maven手动上传的第三方包 打包项目报错 Could not find xxx in central 解决办法

背景: 在Maven私服手动上传了第三方的jar包, 只有jar包, 没有pom文件, 项目在ide中可以正常编译启动,但打包报错无法找到jar包 解决办法: 上传jar包的时候, 点击生成pom. 则打包的时候不会报错

Python判断一个数是否为素数

在Python中&#xff0c;你可以编写一个函数来判断一个数是否为素数。素数是指只有1和它本身两个正因数&#xff08;不包括1本身&#xff09;的自然数。以下是一个简单的示例代码&#xff1a; python复制代码 def is_prime(n): if n < 1: return False if n < 3: return …

pyrealsense2获取保存点云

一、第一种实现代码 Python import sys import cv2 import pyrealsense2 as rs import numpy as np import keyboard import open3d as o3d import osif __name__ "__main__":output_folder output_data/os.makedirs(output_folder, exist_okTrue)pipeline rs.p…

三级数据库技术知识点(详解!!!)

1、从功能角度数据库应用系统可以划分为表示层、业务逻辑层、数据访问层、数据持久层四个层次&#xff0c;其中负责向表示层直接传送数据的是业务逻辑层。 【解析】表示层负责所有与用户交互的功能;业务逻辑层负责根据业务逻辑需要将表示层获取的数据进行组织后&#xff0c;传…

怎样保持SSH长时连接不断开(客户机)

怎样保持SSH连接不自动断开? 一、前言 远程访问服务器的时候&#xff0c;长时间不操作就会断开连接&#xff0c;这让我苦恼不已&#xff0c;因此花了不少时间折腾&#xff0c;因为我用过的很多方法都无效&#xff0c;经过几番测试&#xff0c;找到了一种解决方案。 不过我只…

阅读MySQL知识4

一、MySQL数据库主从同步延迟产生的原因 MySQL的主从复制都是单线程的操作&#xff0c;主库对所有DDL和DML产生的日志写进binlog&#xff0c;由于binlog是顺序写&#xff0c;所以效率很高。 Slave的SQL Thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作…

c# 结构体(Struct)与枚举(Enum)与记录(Record)

结构体(Struct) struct是值类型数据,存储在栈上,原来的值数据一般一般存储单一数据结构定义的数据是记录(存储的数据多). 类也可以存储大量数据,但是类是引用结构,存储在堆上.严谨来说,引用类型的值存储在堆上,引用类型的存储地址存储在栈上. struct的数据成员不能通过初始化器…

鸿蒙:PrefereneceUtil

1、初始化 在EntryAbility.ets中初始化 export default class EntryAbility extends UIAbility {async onCreate(want, launchParam) {// 1.加载用户首选项PreferenceUtil.loadPreference(this.context)hilog.info(0x0000, testTag, %{public}s, Ability onCreate);} } 2、使…

【Centos 轻松一键安装X11 Forwarding,实现无桌面版运行GUI】

#!/bin/bash# 更新系统包索引 echo "更新系统包索引..." sudo yum update -y# 安装X11相关的应用和认证工具 echo "安装X11相关的应用和认证工具..." sudo yum install -y xorg-x11-apps xorg-x11-xauth# 检查和修改/etc/ssh/sshd_config以允许X11转发 ech…

Java中过滤器和拦截器区别

1. 过滤器&#xff08;Filters&#xff09; 过滤器是Servlet规范中的一部分&#xff0c;它用于在请求进入Web应用程序时预处理请求&#xff0c;或在响应离开应用程序前进行处理。过滤器可以作用于请求内容、请求头、响应内容等。过滤器在Servlet容器中运行&#xff0c;并且与S…

Java集合面试题(一)

1. Java 中常用的容器有哪些&#xff1f; 在 Java 中&#xff0c;容器是一种特殊的数据结构&#xff0c;用于存储其他对象。它们可以帮助我们更高效地管理和操作大量的数据。以下是 Java 中常用的几种容器&#xff1a; List&#xff1a;有序集合&#xff08;也是动态数组&…

SpringBoot如何替换启动图标

SpringBoot项目在启动时会出现一个默认的启动图案 . ____ _ __ _ _/\\ / ____ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | _ | _| | _ \/ _ | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) ) |____| .__|_| |_|_| |_\__, | / / / /|_||___//_/_/_/::…

Qt:使用ctrl+z快捷键取消文本框修改

1、使用ctrlz快捷键取消文本框修改 #include <QApplication> #include <QLineEdit> #include <QUndoStack> #include <QVBoxLayout>int main(int argc, char *argv[]) {QApplication a(argc, argv);QWidget window;QVBoxLayout layout(&window);/…

软件架构和基于架构的软件开发方法知识总结

一、软件架构定义 软件架构为软件系统提供了一个结构、行为和属性的高级抽象 软件架构是一种表达&#xff0c;使软件工程师能够&#xff1a; &#xff08;1&#xff09;分析设计在满足所规定的需求方面的有效性 &#xff08;2&#xff09;在设计变更相对容易的阶段&#xff0c;…