自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(56)
  • 收藏
  • 关注

原创 Python接单,交通专业论文辅导

2024-09-11 20:07:38 637

原创 回溯——13.解数独

编写一个程序,通过填充空格来解决数独问题。一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。空白格用 '.' 表示。

2024-09-15 11:43:31 442

原创 回溯——12.N皇后

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

2024-09-15 11:37:14 328

原创 回溯——11.重新安排行程

给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。

2024-09-10 18:03:13 289

原创 回溯——10.全排列 II

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

2024-09-09 18:07:21 355

原创 回溯——9.全排列

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

2024-09-08 11:11:54 492

原创 回溯——8.递增子序列

递归树的构建:程序通过回溯构建一个递归树,每一个节点代表一个数组元素,每条从根到叶的路径代表一个可能的子序列。通过遍历整个递归树,生成所有可能的子序列。递增条件:通过比较当前元素与子序列最后一个元素的大小,保证子序列是递增的。去重:每一层递归中使用set来去重,防止同一层中出现重复的元素。剪枝:通过条件来剪掉不符合递增条件的分支,提升效率。最终,程序返回所有找到的递增子序列。path = []result.append(path[:]) # 注意要使用切片将当前路径的副本加入结果集。

2024-09-07 13:00:32 893

原创 回溯——7.子集II

排序:首先对数组进行排序,便于之后的重复元素跳过处理。回溯法:通过递归遍历所有可能的子集,并在每次递归中将当前路径加入结果集。去重:利用排序后的数组,结合used数组,通过条件和,来跳过同一层中重复的元素,从而避免生成重复子集。path = []nums.sort() # 去重需要排序result.append(path[:]) # 收集子集# used[i - 1] == True,说明同一树枝 nums[i - 1] 使用过。

2024-09-06 21:54:37 549

原创 回溯——6.子集

使用回溯法(backtracking)来解决子集问题,其核心思路是对每一个元素做两种选择:要么将其加入到当前的子集中,要么不加入,并不断递归处理剩下的元素。在每一次递归调用时,都会将当前构造的path加入到result中,确保所有可能的子集都被枚举出来。最终返回的result包含了所有的子集,包括空集。path = []result.append(path[:]) # 收集子集,要放在终止添加的上面,否则会漏掉自己。

2024-09-05 19:25:38 611

原创 回溯——5.复原IP地址

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。例如:"0.1.2.201" 和 "192.168.1.1" 是 有效的 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效的 IP 地址。

2024-09-04 18:36:44 515

原创 回溯——4.分割回文串

这种方法保证了所有可能的回文分割都能被找到,且不会遗漏。通过递归调用,程序可以在不同层次上深入地探索每一种可能的分割方式,一旦路径不符合条件或者到达最终状态,程序会通过回溯来尝试其他可能性。这段代码使用回溯法解决问题,回溯法的核心思想是通过尝试各种可能性来构建解的所有组合。当发现当前路径不满足条件时,撤销上一步的操作(即回溯),并尝试其他路径。

2024-09-01 19:09:42 652

原创 回溯——3.电话号码的字母组合

映射表建立: 通过letterMap将数字0-9与对应的字母集合关联起来。递归生成组合: 使用递归来遍历所有可能的字母组合,递归的每一层处理一个数字,逐层向组合字符串添加对应的字母。终止条件: 当处理完所有数字时,保存生成的组合。返回结果: 最终将所有可能的组合结果存储在result列表中并返回。

2024-08-29 20:22:28 742

原创 回溯——2.组合总和III

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。示例 1: 输入: k = 3, n = 7 输出: [[1,2,4]]示例 2: 输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]]

2024-08-28 18:15:00 541

原创 回溯——1.组合

回溯法是一种非常有效的组合生成策略。它通过在路径中添加元素,并不断递归深入,再回溯撤销操作,确保能够找到所有可能的组合。优化点在于通过控制循环的范围,避免了不必要的计算,从而提升了算法的效率。通过提前计算可以填入组合的数字范围,代码避免了无效的递归,缩减了计算空间。result = [] # 存放结果集returnfor i in range(startIndex, n - (k - len(path)) + 2): # 优化的地方path.append(i) # 处理节点。

2024-08-26 18:33:45 569

原创 二叉树——21.把二叉搜索树转换为累加树

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。提醒一下,二叉搜索树满足下列约束条件:节点的左子树仅包含键 小于 节点键的节点。节点的右子树仅包含键 大于 节点键的节点。左右子树也必须是二叉搜索树。

2024-08-25 15:24:49 507

原创 二叉树——20.将有序数组转换为二叉搜索树

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

2024-08-24 17:15:00 304

原创 二叉树——19.修剪二叉搜索树

给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L)。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。

2024-08-23 17:42:22 977

原创 二叉树——18.删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

2024-08-22 17:49:03 731

原创 二叉树——17.二叉搜索树中的插入操作

给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。返回插入后二叉搜索树的根节点。输入数据保证,新值和原始二叉搜索树中的任意节点值都不同。注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。你可以返回任意有效的结果。

2024-08-21 19:11:58 888

原创 二叉树——16.二叉树的最近公共祖先

递归处理:问题的核心在于使用递归遍历二叉树,从叶子节点开始,逐层向上回溯,寻找p和q的位置。终止条件:当找到节点p或q,或者遍历到空节点时,终止当前递归。返回条件如果在左右子树分别找到了p和q,说明当前节点是最近公共祖先。如果只在一侧找到p或q,返回找到的那个节点。如果两侧都没有找到,返回None。通过这种递归的方式,算法能够高效地找到二叉树中两个节点的最近公共祖先。else:这部分是递归的终止条件。当当前节点root等于pq或者root为空时,直接返回当前节点。这意味着一旦找到p或q。

2024-08-20 18:33:22 551

原创 二叉树——15.二叉搜索树中的众数

这道题的核心思路是通过DFS遍历二叉搜索树,统计每个节点值的出现频率,然后从中找到频率最高的值。由于二叉搜索树的性质,节点值是唯一的,因此通过这种遍历方法能够有效地统计每个值的频率,并最终找到众数。给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。类,它是Python标准库。模块中的一个数据结构。

2024-08-19 18:35:41 462

原创 二叉树——14.二叉搜索树的最小绝对差

中序遍历是一种有效的方法,可以将二叉搜索树节点的值按从小到大的顺序排列。通过将这些值存入一个有序数组后,只需遍历数组,比较相邻元素的差值,即可找到树中任意两个节点值的最小差值。代码中的关键是利用了二叉搜索树的特性,使得中序遍历后得到的序列是有序的,从而简化了最小差值的计算。returnself.vec.append(root.val) # 将二叉搜索树转换为有序数组return 0# 统计有序数组的最小差值Solution类是一个包含解决方案的类。在类的构造函数__init__

2024-08-18 10:56:43 603

原创 二叉树——13.验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。二叉搜索树性质:基于这个性质,如果我们对一棵二叉搜索树进行,我们会得到一个的有序数组。这一特性是解决问题的关键。

2024-08-17 10:33:28 871

原创 二叉树——12.二叉搜索树中的搜索

二叉搜索树的性质:二叉搜索树是每个节点的左子树节点值小于该节点的值,右子树节点值大于该节点的值。正是利用这个性质,可以在树中高效地搜索目标值。递归:这个方法使用了递归的思路,在树中搜索目标节点。每次递归调用都在减少搜索范围(要么在左子树,要么在右子树),从而逐步逼近目标值。返回值的关键性:代码中的return语句是核心部分。当在当前节点找到目标值时,立即返回该节点,停止进一步的递归。这也是为什么必须有返回值的原因:如果没有return,递归调用会继续下去,最终遍历整棵树,而这显然不是我们期望的搜索行为。

2024-08-16 20:31:26 664

原创 二叉树——11.合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。在本题中,递归用于合并两棵树的每个节点。如果两棵树的当前节点都存在,则将它们的值相加,并递归合并它们的左子树和右子树。在这个算法中,我们重复使用了原有的树节点,而不是创建新的树节点。,即合并后的树的根节点。这是合并树的核心逻辑,表示将两个节点的值合并到一起。就是合并后的树的根节点。

2024-08-15 18:48:35 595

原创 二叉树——10.路径总和

在遍历过程中,不断更新当前路径的节点值之和,判断是否能够达到目标和。:如果当前节点的左右子树都没有找到满足条件的路径,那么需要回溯,即撤销对当前节点的处理,并继续探索其他可能的路径。给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。首先,检查当前节点是否是叶子节点(即没有左子节点和右子节点),并且剩余目标和为零。如果当前节点的左右子节点都不存在满足条件的路径,则返回。表示从目标和中减去根节点的值,剩下的值将作为新的目标和传递给。,表示不存在任何路径。

2024-08-14 18:23:35 715

原创 二叉树——9.找树左下角的值

初始队列为[1],队列存在数进入while循环,弹出队列最左侧的数1作为node,1存在右子节点3,则当前队列为[3],1存在左节点2,则当前队列为[3,2]。队列存在,弹出队列最左侧节点3作为node,3存在右子节点,则当前队列为[2,6],3存在左子节点,则当前队列为[2,6,5]。在该道题目中,按上述代码进行提交,结果是正确的,所以在该题目中如果最下层只有一个节点,且该节点为右叶子,那这个右叶子算这棵树的左下角的值。题干很简单,找到树的最后一行,在该行找到最左边的值,结合完整代码进行分析。

2024-08-13 19:49:48 945

原创 二叉树——8.左叶子之和

其次,开始递归计算左子树中的左叶子节点值的和。首先检查当前节点的左子节点是否存在,并且该左子节点没有左孩子和右孩子,如果满足条件,说明root.left是一个左叶子节点。将左子节点值赋值给leftValue。首先,判断当前节点是否为空,如果当前节点为空就返回0;判断当前节点有没有左右子节点,如果既没有左子节点也没有右子节点(说明它是一个叶子节点),也返回 0。同理计算右子树中左叶子节点的和,最后相加得到sum_val。计算给定二叉树的所有左叶子之和。首先,分析左叶子到底是什么?

2024-08-12 18:04:33 332

原创 二叉树——7.二叉树的所有路径

这个算法使用深度优先搜索 (DFS) 方法来遍历二叉树,记录从根节点到每个叶子节点的路径。每当到达一个叶子节点时,构造一个代表路径的字符串,并将其添加到结果列表中。通过回溯path.pop()来确保每次递归调用后路径能够恢复到正确的状态,从而继续其他分支的遍历。

2024-08-11 10:32:26 661

原创 二叉树——6.平衡二叉树

分别利用递归计算左右子树的高度,通过递归调用get_height函数,然后将左子树高度存储在left_height中,如果left_height等于-1,说明左子树不平衡,返回-1。代码中的:=代表什么?但你这是在递归,你在一层中随意返回一个不等于-1的值,那其余层递归内,怎么确定节点高度?调用get_height方法来获取树的高度,如果get_height返回的结果不为-1,则表示树是平衡的,返回True;平衡二叉树的定义是,对于二叉树的每一个节点,它的左子树和右子树的高度差不超过1。

2024-08-10 10:26:10 687

原创 二叉树——5.完全二叉树的节点数

有些人一看示例root = [1,2,3,4,5,6],就想求节点数,那我之间求这个数组长度不就行了么?很简单,但凡一个节点存在子节点,那左节点必须存在,这样的树才能称为完全二叉树。: 递归调用 getNodesNum(cur.right),计算右子树的节点数量,结果存储在 rightNum 中。: 递归调用getNodesNum(cur.left),计算左子树的节点数量,结果存储在leftNum 中。: 左子树节点数 + 右子树节点数 + 当前节点本身(1),存储在treeNum中。

2024-08-09 19:00:23 376

原创 二叉树——4.二叉树的最小深度

当左子树为空,右子树不为空时,那么在右子树上开始递归,直到找到最小深度再加上根节点的1;如果都为空,但根节点左子树深度为3,右子树深度为4,那就求最小值min(leftDepth, rightDepth)再加上根节点的1。题干很简单,跟上一节的区别不大,上一节找的是最大深度,这一节找的是最小深度。怎么判断是不是最小深度呢?一个父节点下两个子节点,如果左节点下没有树了,而右节点下还有继续的树,那左节点树的深度肯定比右节点小,根据这个思路可以编写代码。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

2024-08-08 19:18:43 209

原创 二叉树——3.二叉树的最大深度

根据leftheight = self.getdepth(node.left),可以一直到最左侧的节点3,3往下没有了为0,那3这一层的高度为1,3往上一层的节点为2,2还有一右节点,符合 rightheight = self.getdepth(node.right),开始对其进行递归,直到最底层,这样不停递归,height = 1 + max(leftheight, rightheight)选取子树中最长的一个加上根节点一层,得到整个树最长的一条路线。说明: 叶子节点是指没有子节点的节点。

2024-08-07 18:48:43 197

原创 二叉树——2.对称二叉树

比如4和4,最底层的outside = self.compare(left.left, right.right) 完成后开始往上走,左侧的父节点3还有右节点5,右侧的父节点3还有左节点5,进入inside = self.compare(left.right, right.left),判断后再往上走,发现和3同层的还有节点6,开始进入6子树,依旧是outside = self.compare(left.left, right.right)直到底层。开始一层一层往上往里进行递归判断内测的节点是否相等。

2024-08-06 19:35:20 1343

原创 二叉树——1.翻转二叉树

将每个父节点下的子节点互换就行了,4下面2分支树和7分支树互换,2下面1和3互换,7下面6和9互换。在前面可以自学一下关于二叉树的理论基础,二叉树的遍历形式上分为3种,前序遍历、中序遍历和后序遍历,分别对应父节点和子节点。前序遍历(中左右)、中序遍历(左中右)、后序遍历(右中左),三种遍历又分别可以用递归法和迭代法,可以挑一种作为自己精通掌握的,再了解其他方法做到融会贯通。互换当前父节点下的左右节点,分别将左右节点利用invertTree函数进行递归,直到最后不存在下一个节点。

2024-08-05 19:47:51 200

原创 栈和队列——4.前k个高频元素

定义一个大小为k的空数组,因为堆每次弹出的是最小的,但要求的结果数组是由大到小排列的,所以我们要从数组最后开始填充for i in range(k-1, -1, -1),从k-1索引(即数组最后)到能取到的0,每次以-1的步长。这里为元素值,而不是元素的次数,由于是小顶堆,所以这三个中3是对应次数最小的,即以1——2——3的顺序排列,因为k=2,那我在堆中再进行一次弹出,弹出了3,留下了[1,2]。根据示例中[1,1,1,2,2,3],‘1’有3次,‘2’有2次,‘3’有1次,那我小顶堆长什么样子呢?

2024-08-04 11:27:34 1271

原创 栈和队列——3.滑动窗口最大值

接着开始移动滑动窗口,首先推出滑动窗口第一个数,这里就可以解释我们上文在pop函数定义时留下的问题了,理论上滑动窗口第一个数nums[i-k]需要被推出,但类似示例中这种情况时,首次滑动窗口的1,3,-1,推出nums[i-k]=nums[0]=1,但1在push进入队列时就已经被推出了,要推出的值value不等于队列中的第一个数代表着在push过程中就已经被推出了,那我还要推出吗,那就不需要了,1,3,-1中按规则3还能参加下一次滑动窗口,因此在pop函数中定义了这一规则。返回滑动窗口中的最大值。

2024-08-03 13:02:33 1022

原创 栈和队列——2.逆波兰表达式求值

在字符是运算符的情况下,推出栈中的两个元素op2(后进的数)和op1(先进的数),然后将self.op_map[token](op1, op2)压入栈,op_map[token]找到运算符对应的运算函数,例如“+”对应add,则self.add(op1, op2)。这里也可以解释上面提出为什么要用函数表示的问题,你如果用函数表示,这里的代码不好编写。用栈的思维理解就是,列表一个数一个数进栈,当发现当前要进栈的是运算符,那就从栈中吐出两个数用运算符进行运算,运算得到的数再进栈,一直重复直到最后得到值。

2024-08-02 20:15:44 660

原创 栈与队列——1.有效的括号

你可以这样理解,从左开始最外层的括号对应的右半部分也是该组合括号的最外层,最内层的括号对应的右半部分也是该组合括号的最内层,这样才能构成有效的括号组。所以当遇到括号左半部分,类似(时,就在stack中添加),这样遇到括号右半部分按顺序出栈的时候才能完全抵消。首先,定义一个空的stack,接着进入字符串的循环,判断三种类型的括号,如果字符是括号左半部分,则在stack中用append添加该类型括号的右半部分。给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

2024-08-01 21:10:34 282

原创 字符串——3.重复的子字符串

首先,我们来分析一下这个自定义函数getNext,在分析之前,我先简单讲一下这个解法的原理,如果字符串s是由它的子串重复构成的,那么一定存在两种特征,一是最小子串的长度是能被原始子串s长度整除的(这个很容易理解,最小子串长度如果是3的话,那你重复构成的s长度肯定是3的倍数吧);那么题目就转化为了在s+s中寻找有没有s,利用python中的find函数就可以完成了,但是在s+s中寻找s总感觉奇奇怪怪的,既然是s+s那其中不本来就有s么,怎么判断是原始的s还是新组成的字符串中的s呢?首先判断nxt[-1]!

2024-07-31 19:19:10 1297

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除