- 博客(28)
- 收藏
- 关注
原创 代码随想录算法训练营第三十天| 452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间
此时问题就是要求非交叉区间的最大个数。
2024-09-25 20:57:42 188
原创 代码随想录算法训练营第二十九天| 134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列
局部最优可以推出全局最优,找不出反例,试试贪心!
2024-09-25 16:41:09 485
原创 代码随想录算法训练营第二十八天| 122.买卖股票的最佳时机 II、55. 跳跃游戏、45.跳跃游戏 II、1005.K次取反后最大化的数组和
122. 买卖股票的最佳时机 II其实我们需要收集每天的正利润就可以,收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润,不需要记录区间。那么只收集正利润就是贪心所贪的地方!局部最优:收集每天的正利润,全局最优:求得最大利润。55. 跳跃游戏55. 跳跃游戏贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。这道题目关键点在于:不用拘泥于每次究竟跳几步,而是看覆盖范围,覆盖范围内一定是可以跳过来的,不用管是怎么跳的。大家
2024-09-25 00:14:26 415
原创 代码随想录算法训练营第二十七天| 455.分发饼干、376. 摆动序列、53. 最大子序和
。所以唯一的难点就是如何通过局部最优,推出整体最优。那么如何能看出局部最优是否能推出整体最优呢?有没有什么固定策略或者套路呢?靠自己手动模拟,如果模拟可行,就可以试一试贪心策略,如果不可行,可能需要动态规划。有同学问了如何验证可不可以用贪心算法呢?。这个四步其实过于理论化了,我们平时在做贪心类的题目 很难去按照这四步去思考,真是有点“鸡肋”。做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。。
2024-09-24 19:17:03 330
原创 代码随想录算法训练营第二十六天| 332.重新安排行程、51. N皇后、37. 解数独
当回溯算法使用void返回类型时,算法会遍历所有可能的路径,直到所有可能性都尝试完毕。即使某条路径找到了解(满足了某个条件),使用bool返回值时,可以在找到解之后立即停止进一步的递归。在 C++ 中,std::map是一个,默认情况下使用(从小到大)对键进行排序。如果键是字符串类型(如机场代码),则根据字典顺序进行排列。
2024-09-24 17:16:26 370
原创 代码随想录算法训练营第二十五天| 491.递增子序列、46.全排列、47.全排列 II
本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。
2024-09-22 16:16:57 254
原创 代码随想录算法训练营第二十四天| 93.复原IP地址、78.子集、90.子集II
全局变量数组path为子集收集元素,二维数组result存放子集组合。(也可以放到递归函数参数里)本题也可以不使用used数组来去重,因为递归的时候下一个startIndex是i+1而不是0。其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。如果要是全排列的话,每次要从0开始遍历,为了跳过已入栈的元素,需要使用used。如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,递归函数参数在上面讲到了,需要startIndex。
2024-09-21 21:19:30 348
原创 代码随想录算法训练营第二十三天| 39. 组合总和、40.组合总和II、131.分割回文串
本题递归函数参数还需要startIndex,因为切割过的地方,不能重复切割,和组合问题也是保持一致的。前面我们提到:要去重的是“同一树层上的使用过”,如何判断同一树层上元素(相同的元素)是否使用过了呢。, 给定起始下标和终止下标, 截取出的子字符串是否是回文字串。上面的代码还存在一定的优化空间, 在于如何更高效的计算一个子字符串是否是回文字串。作为参数,并返回一个新构造的字符串对象,其值初始化为该对象的子字符串的副本。()是用于字符串处理的预定义函数。是字符串函数所需的头文件。具体来说, 给定一个字符串。
2024-09-14 17:03:28 386
原创 代码随想录算法训练营第二十二天| 第77题. 组合、216.组合总和III、17.电话号码的字母组合
回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯是递归的副产品,只要有递归就会有回溯。。,如果想让回溯法高效一些,可以加一些剪枝的操作,但也改不了回溯法就是穷举的本质。那么既然回溯法并不高效为什么还要用它呢?因为没得选,一些问题能暴力搜出来就不错了,撑死了再剪枝一下,还没有更高效的解法。
2024-09-09 00:54:02 777
原创 代码随想录算法训练营第二十一天| 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
首先取数组中间元素的位置,不难写出。
2024-09-08 11:09:26 279
原创 代码随想录算法训练营第二十天| 235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点
二叉搜索树是有序的,当我们从上向下去递归遍历,第一次遇到 cur节点是数值在[q, p]区间中,那么cur就是 q和p的最近公共祖先。而递归遍历顺序,本题就不涉及到 前中后序了(这里没有中节点的处理逻辑,遍历顺序无所谓了)。根据数值大小找最近公共祖先,搜索某条边递归。
2024-09-08 00:10:17 238
原创 代码随想录算法训练营第十八天| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。以上代码是把二叉搜索树转化为有序数组了,其实在二叉搜素树中序遍历的过程中,我们就可以直接计算了。,二叉搜索树可是有序的。
2024-09-07 13:35:52 162
原创 代码随想录算法训练营第十七天| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
即使你的逻辑已经处理完所有可能性,C++ 还是要求在每一条可能的执行路径上都有明确的返回值。以上代码中,我们把二叉树转变为数组来判断,是最直观的,但其实不用转变成数组,可以在递归遍历的过程中直接判断是否有序。对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。不可能在初始化一个更小的值了吧。样例中最小节点 可能是int的最小值,如果这样使用最小的int来比较也是不行的。,这明确告诉编译器,在前两个条件不成立的情况下,剩下的唯一路径就是。这是因为编译器的规则是,
2024-09-05 15:07:31 290
原创 代码随想录算法训练营第十六天| 513.找树左下角的值、112. 路径总和、113. 路径总和 II、106.从中序与后序遍历序列构造二叉树、105.从前序与中序遍历序列构造二叉树
下面给出用下标索引写出的代码版本:(思路是一样的,只不过不用重复定义vector了,每次用下标索引来分割)
2024-09-05 10:30:07 406
原创 代码随想录算法训练营第十五天| 222.完全二叉树的节点个数、110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和
在这种情况下,不需要回溯是因为你通过不可变的字符串拼接方式实现了路径的构建,每次递归都生成了一个新的字符串对象,递归过程本身就确保了路径的独立性。相比之下,使用回溯的情况通常发生在路径或状态是可变对象(如数组或vector)时,需要在递归返回后恢复状态以继续其他路径的探索。这个方法的优点是代码更加简洁,避免了不必要的回溯操作,缺点可能是在涉及大量路径时,由于字符串拼接操作可能会带来一些性能开销。注意在函数定义的时候,定义的是,每次都是复制赋值,不用使用引用,否则就无法做到回溯的效果。
2024-09-04 15:01:07 997
原创 代码随想录算法训练营第十四天| 226.翻转二叉树、101. 对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度
参数就是要传入节点的指针,不需要其他参数了,通常此时定下来主要参数,如果在写递归的逻辑中发现还需要其他参数的时候,随时补充。返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*。当前节点为空的时候,就返回因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。
2024-09-03 15:47:57 143
原创 C++算法中一些知识点
时间复杂度:定义:时间复杂度衡量的是算法执行过程中最耗时的部分随着输入规模 nnn 的增长,执行次数如何变化。 分析重点: 最费时间的部分:在分析一个函数的时间复杂度时,我们主要关注的是最费时间的操作部分。例如,循环体中的操作、递归中的深度计算、或其他需要多次执行的部分。 次数计算:我们需要计算最费时间的操作部分在最坏情况下会执行多少次。这通常是最内层循环的执行次数,或者是最复杂的递归调用次数。 大 O 表示法:最后,我们用大 O表示法来表示时间复杂度,忽略掉常数因子和低阶项,只关注随着输
2024-08-25 23:41:21 210
原创 代码随想录算法训练营第十一天| 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
单调队列不是一成不变的,而是不同场景不同写法,总之要保证队列里单调递减或递增的原则,所以叫做单调队列。C++中deque是stack和queue默认的底层实现容器,deque是可以两边扩展的,而且deque里元素并不是严格的连续分布的。,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。头文件中的一个模板类,用于比较两个值的大小,默认实现为“>`”。由于我们希望建立一个小顶堆,这个比较器实现了这样的需求。:定义了一个比较器类,其中的。,这意味着在堆的结构中,
2024-08-25 10:24:41 602
原创 代码随想录算法训练营第十天| 232.用栈实现队列、225. 用队列实现栈、20. 有效的括号、1047. 删除字符串中的所有相邻重复项
peek()直接使用已经写好的pop()创建一个对象时,编译器会自动为该对象生成一个指向它自身的特殊指针,这个指针就是this指针。在 C++ 中,this指向调用成员函数的对象自身,并且只能在非静态成员函数中使用。
2024-08-24 17:08:00 238
原创 代码随想录算法训练营第九天| 151.翻转字符串里的单词、右旋字符串、28. 实现 strStr()、459.重复的子字符串
while自定义的函数,引用传递参数。
2024-08-24 10:59:25 414
原创 代码随想录算法训练营第八天| 344.反转字符串、541. 反转字符串II、替换数字
如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,可以考虑使用库函数。swap可以有两种实现。
2024-08-23 17:52:34 430
原创 代码随想录算法训练营第七天| 454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和
四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下标作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况,三数之和的时间复杂度是O(n^2),四数之和的时间复杂度是O(n^3)。在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!,所以循环不会执行,不会发生越界访问。,这时循环条件会立刻为。
2024-08-23 13:26:17 436
原创 代码随想录算法训练营第六天| 242. 有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和
242. 有效的字母异位词242. 有效的字母异位词当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。数组其实就是一个简单哈希表,数量比较少、的时候可以使用class Solution {public: bool isAnagram(string s, string t) { int record[26]={0};
2024-08-22 15:14:18 446
原创 代码随想录算法训练营第四天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II
快慢指针 fast走两个,slow走一个 如果有环会相遇。双指针(快慢指针) 虚拟头节点。slow指向处理节点的上一个。如果相遇的话,找入口有难度。
2024-08-17 17:36:16 168
原创 代码随想录算法训练营第三天| 203.移除链表元素、707. 设计链表、206. 反转链表
使用虚拟头节点,以一种统一的逻辑来移除链表的节点,注意链表结构体定义操作某个节点是指向他上一个节点,cur->next来操作下一个节点: 这样可以避免复制整个数组的开销,同时保持对数组内容的直接访问。引用可以确保传递的数据是原始的,而不是副本。: 由于链表节点通常是动态分配的,指针允许函数对链表进行修改(如添加或删除节点)。使用指针也更适合链表的结构操作,例如遍历、修改节点等。->cur->next是一种简化的写法,等价于。箭头操作符 (->) 直接访问指针所指向对象的成员。
2024-08-16 16:39:07 188
原创 代码随想录算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II、58.区间和、开发商购买土地、44. 开发商购买土地
滑动窗口也可以理解为双指针法的一种,只不过这种解法更像是一个窗口的移动每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。三元运算符 条件表达式1?表达式2 : 表达式3;可以用来简化if语句INT_MAX。
2024-08-16 10:13:20 392
原创 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素、977.有序数组的平方
写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。暴力的解法就是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。vector初始化方式 vector result(nums.size,0)暴力排序最直观的想法,莫过于:每个数平方之后,排个序。双指针法,两端指针比较大小。
2024-08-15 21:06:46 229
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人