- 博客(73)
- 收藏
- 关注
原创 编程题-最长公共子序列(中等-二维动态规划(重点))
1、动态规划方法的实现需要确定两个必要条件,一个是边界条件;另一个是状态转移方程。可以通过迭代或递归的方式实现。当满足if条件语句时,激活状态转移方程。2、关于字符串根据索引值获取字符的操作:at() 与 operator[] 比较:operator[] 不进行越界检查。如果索引越界,会导致程序崩溃或未定义行为。at() 会进行越界检查,如果访问的索引无效,它会抛出一个 std::out_of_range 异常。
2025-03-26 08:00:00
798
原创 编程题-零钱兑换II(中等-动态规划(重点))
笔者小记:1、动态规划思想可极大降低时间复杂度,需特别关注。2、“||”与“|”运算符号的区别:仅仅是函数调用时的区别,数值上并没有区别。||(逻辑或)运算符有短路行为,即如果左边的操作数为 true,右边的操作数就不会被计算,因为结果已经确定为 true。这是为了优化性能。|(按位或)运算符没有短路行为,无论左边和右边的操作数是什么,都会计算左右两边的每个操作数。
2025-03-25 08:00:00
781
原创 编程题-爱吃香蕉的珂珂(中等-二分查找优化的应用)
笔者小记:1、二分查找的优化应用:二分查找是一种非常高效的查找算法,通常用于在 有序 数组或区间中查找某个特定值或满足某个条件的值。二分查找的时间复杂度为 O(log n),相比于顺序查找的 O(n)。因此,可以将原本解法一中时间复杂度为O(n^2)的问题降低为时间复杂度为O(n*logn)的问题。2、在本题中,由于查找的某个特定值在有序数组或区间中,与问题的目标数值存在单调关系(可以通过目标值结果反馈给二分查找下一次迭代取值方向)。因此,可以通过二分查找对for循环依次遍历得到结果的过程进行优化。
2025-03-24 08:00:00
958
原创 编程题-网络延迟时间(中等-最优化算法)
笔者小记:1、DijKstra算法;2、堆的数据结构;3、max_element()函数。4、pair<int,int>类型
2025-03-21 08:00:00
1520
原创 编程题-课程表(中等-重点)
笔者小记:1、拓扑排序原理及应用;2、拓扑排序实现通过深度优先搜索结合栈的数据结构实现,或者广度优先搜索结合队列数据结构实现。
2025-03-20 08:00:00
882
原创 编程题-任务调度器(中等-最优化算法)
笔者小记:1、通过使用合适的数据结构,记录并更新过程中关键信息【元素】,实现较低时间复杂度算法的实现。(优化点:不需要不断增加1,模拟一个时间片,通过构建数据结构记录最小冷却执行时间,将哪些在times一次都遍历执行任务的过程跳过,降低时间复杂度);2、task.size()为需要执行的所有任务的总次数,不需要保证数组为空时终止(每次执行时,剩余执行数量为0的数组进行删除)。通过best遍历所有任务的剩余未执行任务最多的是哪个任务的时间复杂度为O(n),可以避免排序操作时间复杂度为O(nlog(n))。
2025-03-19 08:00:00
962
原创 编程题-每日温度(中等)
笔者小记:1、题目提示信息的利用(常数项的for循环可降低时间复杂度):利用题目给定的一些提示信息,可以创建常数量的数组(数据结构),减少时间复杂度O(n^2)的产生。2、单调栈的利用:单调栈是一种特殊的栈,通常用于解决一些涉及序列元素比较的问题,如寻找下一个更大或者更小的元素。它具有一个特殊的性质:栈中的元素保持单调顺序。单调栈可以是单调递增栈或单调递减栈。单调栈在许多常见的算法题中非常有用,尤其是处理与数组或序列相关的问题时,通过利用栈的特点可以有效地优化时间复杂度。
2025-03-17 14:18:47
831
原创 编程题-最长重复子数组(中等)
笔者小记:1、暴力枚举方法的时间复杂度为O(n^3)过长,可以通过使用动态规划思想或滑动窗口思想并结合合适的数组结构,以降低代码的时间复杂度,目的是尽可能减少数组元素的重复遍历访问情况。
2025-03-17 10:32:38
1000
原创 编程题-马戏团人塔(中等-重点)
笔者小记: 1、sort()函数自定义排序;std::lower_bound用于在有序序列中查找第一个大于等于目标值的元素的位置。
2025-03-14 08:00:00
885
原创 编程题-找到字符串中所有字母异位词(中等)
笔者小记:1、滑动窗口思想及其优势:滑动窗口是一种常用于处理数组或序列类问题的算法思想。它的核心思想是利用两个指针(通常是左指针和右指针)来维护一个窗口范围,并随着窗口的滑动来更新答案。滑动窗口能够在很多场景下优化时间复杂度,尤其是对于需要遍历和比较多个子数组或子序列的问题;减少冗余计算:避免了重复遍历数组或子数组的情况,减少了不必要的计算量,通常能够将时间复杂度从O (n^2)降到 O(n)。2、数组和哈希表计数的方式:可以通过将哈希表和数组计数的方式,可以通过直接判断是否相等。
2025-03-13 11:19:23
927
原创 编程题-计算器(中等)
笔者小记:1、isdigit()函数表示判断是否是阿拉伯数字0~9,若是返回true,否则返回false。2、accumulate(stk.begin(), stk.end(), 0)函数表示用来对指定范围内元素求和。3、switch{}函数中关键词break是为了通常会在每个 case 块的末尾使用 break 语句来避免“穿透”(fall-through)问题。
2025-03-09 22:58:05
516
原创 编程题-去除重复字母(中等)
笔者小记:1、提示中s均为26个小写英文字符,则可以定义vector<int>数组用于计数和判断在某一(另一个数据结构)中存储出现情况。2、相比利用哈希表,利用单调栈(string类型的)和vector<int>(技术和判断是否出现情况)可以更好的实现低时间复杂度的一次遍历情况。
2025-03-03 08:00:00
1064
原创 编程题-打家劫舍 II(中等-重点)
笔者小记;在利用动态规划算法进行解题时,第一要考虑动态转移方程(状态转移方程:找出 dp[i] 和 dp[i-1]、dp[i-2] 等之间的关系),第二要考虑边界条件(即指的是在递归或迭代过程中,不需要再拆分的问题,即可以直接得到结果的情况。边界条件的设置对于正确构建 DP 递推公式至关重要,边界条件是初始化 DP 数组:为后续状态转移提供基础。提供直接解:有些问题在初始状态下答案已知,无需进一步计算)。除此之外,动态规划/贪心算法思想一般都会先分成两类,并取两个最后大规模问题最优解之间的最大值,作为最终解
2025-03-02 13:59:25
1071
原创 编程题-最大数(中等)
笔者小记:1、字符串比较,在C++中,std::string 类型的字符串可以通过直接使用比较运算符进行大小比较。比较是基于字典顺序(即按字符的 ASCII 或 Unicode 值逐一比较)进行的2、关于sort()排序函数的高阶使用。
2025-02-28 08:00:00
795
原创 编程题-LRU缓存(中等)
笔者小记:1、在C++中,当需要使用有先后顺序的哈希表时(即有序哈希表),可以采用哈希表+双向链表的方式实现,原本C++中并不支持有序哈希表的数据结构。2、将一个节点移动到双向链表的头部,可以分成【删除该节点】和【在双向链表的头部添加节点】两部操作,都可以在O(1)时间内完成。3、在双向链表的实现中,使用一个伪头部和伪尾部标记界线,这样在添加节点和删除节点的时候就不需要检查相邻的节点是否存在。
2025-02-26 08:00:00
929
原创 编程题-从前序与中序遍历序列构造二叉树(中等-重点)
笔者小记:1、掌握二叉树前序遍历和中序遍历的过程;2、掌握二叉树构建时,通过递归和迭代的方式添加二叉树新节点的代码书写思路。
2025-02-24 22:11:09
1075
原创 编程题-连接两字母单词得到的最长回文串(中等)
笔者小记:在遍历哈希表中的每个单词时,为了避免重复计算成对选择的单词,我们可以设置访问标记符,哈希表初始访问符设置为0,在后续遍历中将已访问的哈希表元素的标记符修改为1,添加if条件语句仅遍历标记符为0的哈希表元素,可减少时间复杂度,避免重复访问成对选择的哈希表元素。
2025-02-23 22:39:56
695
原创 编程题-颜色分类(中等)
笔者小记:1、采用指针思路时,指针可以作为满足特定条件后再移动,而不需要每次循环遍历就需要移动,即for循环遍历是,int i是与p0、p1或p2独立分开的。p0、p1或p2只是记录元素【头部】的一个标记点。
2025-02-17 21:34:24
991
原创 编程题-合并区间(中等-重点)
笔者小记:1、对于vector<vector<int>>& intervals,函数sort(intervals.begin(), intervals.end());表示利用intervals内层的第一个元素的大小对intervals外层元素进行排序。
2025-02-16 23:32:25
814
原创 编程题-最大子数组和(中等-重点【贪心、动态规划、分治思想的应用】)
笔者小记:1、动态规划与分治法和贪心法类似,都是将问题分解为更小的子问题,并通过求解子问题来得到全局最优解。然而,它们在处理子问题的方式上有所不同: 贪心法:当前选择依赖于已经作出的所有选择,但不依赖于有待于做出的选择和子问题。它自顶向下,一步一步地作出贪心选择。 分治法:各个子问题是独立的,一旦递归地求出各子问题的解后,自下而上地将子问题的解合并成问题的解。 动态规划:允许子问题不独立,通过自身子问题的解作出选择,对每一个子问题只解一次,并将结果保存起来,避免每
2025-02-15 18:22:44
1144
原创 编程题-字母异位词分组(中等-重点)
笔者小记:1、采用sort()函数不仅可以对数组进行排序,而且可以对string类型的字符串进行排序,确定两个字符串是否是字母异位词,可以加快两个string类型字符串的判断。2、采用高阶哈希表unordered_map<string, vector<string>>可以有效地降低时间复杂度,仅通过一次for循环便可以遍历并添加所有满足条件的键值对,减少利用多层for循环导致元素重复访问引起的时间超限。
2025-02-14 14:40:12
927
原创 编程题-组合总和(中等)
笔者小记:1、emplace_back 函数的调用方式类似于 push_back,但它接受一个或多个参数,这些参数直接用于在 vector 的末尾构造新的元素。这些参数会传递给元素的构造函数。2、回溯算法是将整个搜索过程用一个树来表达,每次的搜索都会延伸出两个分叉,直到递归的终止条件,这样我们就能不重复且不遗漏地找到所有可行解,当然,搜索回溯的过程一定存在一些优秀的剪枝方法来使得程序运行得更快【剪枝为跳出函数的边界条件,可加速执行效率】。
2025-02-13 14:05:41
682
原创 编程题-在排序数组中查找元素的第一个和最后一个位置(中等)
1、对于已经排列的单调递增数组,我们可以利用二分法来加速查找的过程,避免依次遍历所有数组元素【时间复杂度为O(n)】,利用二分法查找数组元素可将时间复杂度降低至O(logn)。
2025-02-13 10:55:00
678
原创 编程题-括号生成(中等)
回溯法一般是在集合中递归搜索【for循环 (一个节点有多少个孩子,就执行多少次) 或者if条件语句 ( 枚举列出可能会产生的等可能情况)】,集合的大小构成了树的宽度,递归的深度构成了树的深度。
2025-02-04 19:22:43
707
原创 编程题-电话号码的字母组合(中等)
笔者小记:1、vector<string>& combinations;const unordered_map<char, string>& phoneMap;const string& digits;string& combination中 “&” 符号表示传递的引用,可以随时修改。2、combination.pop_back()中的.pop_back()函数,表示将conbination字符串类型的对象去除容器顶部的一个字符类型元素。
2025-02-03 23:08:57
746
原创 编程题-最接近的三数之和(中等)
如果a1+a2+a3≥target,并且我们知道a2和a3这个范围是按照升序排列的,那么如果a3不变而移动a2向右,那么a1+a2+a3的值就会不断地增加,显然就不会成为最接近target的值了。实际上,a2和a3就表示我们当前选择的数的范围,而每一次枚举的过程中,我们尝试边界上的两个元素,根据它们与target的值的关系,选择【抛弃】左边界的元素还是右边界的元素,从而减少了枚举的范围。,我们用a2和a3作为双指针,初始时,a2指向位置i+1,即左边界,a3指向位置n-1,即右边界。
2025-02-01 14:43:50
1095
原创 编程题-三数之和(中等)
笔者小记:1、指针移动(或者说指针的增减操作)在 C++ 中的时间复杂度是 O(1),即常数时间复杂度,相比单层循环时间复杂度为O(N),多使用指针思想代替for循环可以大大降低时间复杂度,避免时间超限。
2025-01-30 13:39:55
1394
原创 编程题-最长的回文子串(中等-重点)
对于编程问题实现过程中非常需要注意的是时间复杂度的影响,尽可能避免使用多层for循环,这样极容易使时间超限!!!
2025-01-28 17:35:35
1737
原创 编程题-盛最多水的容器(中等-重点)
每次都移动自己最差的一边,虽然可能变得更差,但是总比不动(或者减小最强的一边)强,动最差的部分可能找到更好的结果,但是动另一边总会更差或者不变,兄弟们,这不是题,这是人生,逃离舒适圈!!
2025-01-26 19:57:22
974
原创 编程题-两数相加(中等)
1、int n1 = l1 ? l1->val: 0;判断l1是否为空,若不为空(True)则 int n1 = l1->val,若为空(False)则 int n1 = 0;其中如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0。进行补零操作。2、head = tail = new ListNode(sum % 10);其中包括连续赋值操作以及直接通过new ListNode()创建新的链表节点。特别注意地是new关键字不仅是链表创建并添加新的链表节点的方式,也是二叉树添加新节点的方式。
2025-01-23 23:38:24
974
原创 编程题-招式拆解II
本题考察哈希表的使用,本文介绍“哈希表”和“有序哈希表”两种解法,其中,在字符串长度较大、重复字符很多时,“有序哈希表”解法理论上效率更高。
2025-01-19 08:30:00
879
原创 编程题-生成交替二进制字符串的最小操作数
除了使用恰当合适的数据结构以简化代码编写,更快速便捷的实现问题解决之外,还需要考虑问题分类时所产生的一些性质和关系,这些相比使用更“高级”的数据结构,可以大大降低解决问题的复杂度【时间复杂度(for循环的使用)和空间复杂度(数据结构所存储的数据)】,实现代码“质”的优化。
2025-01-18 08:30:00
694
原创 编程题-最小高度树
笔者小记:1、创建一个新的空二叉树,TreeNode* root = nullptr;必须加*指针,否则会产生错误。2、创建二叉树的索引TreeNode*& root,后续对root的修改则会直接修改原来的二叉树,必须加&引用符号,否则后续对root的修改只会改变函数体内的root二叉树,不能对函数体外root二叉树内容进行修改。TreeNode*& root是一个引用类型的指针参数,它表示传递的是指向TreeNode*的引用,当传递给函数时,函数内部可以直接修改原始root指针的值,甚至可以改
2025-01-17 08:30:00
746
原创 编程题-寻找二叉搜索树中的目标节点
1、二叉搜索树中序遍历为“左、根、右”顺序,得到的结果是由小到大倒序排列的,而二叉搜索树中序遍历的倒序为” 右、根、左“顺序,得到的结果是由大到小倒序排列的。2、如果在类的成员函数中有一个形参名为cnt,而类中也有一个名为cnt的成员变量,这种赋值操作是必须的,因为编译器无法自动区分同名的成员变量和函数参数,通过this->cnt,明确地告诉编译器访问的是类的成员变量,而不是函数的参数。
2025-01-16 08:45:00
563
原创 编程题-二叉搜索树节点最小距离
二叉树遍历可通过前序遍历,中序遍历,后序遍历等操作实现,通过栈、队列、递归函数等数据结构方式完成,在解决问题的同时,可多利用C++标准数据库中的函数简化代码量,例如sort()排序函数,min(),max()比较最大最小值计算函数,swap()交换数组函数等
2025-01-16 08:30:00
612
原创 编程题-螺旋遍历二维数组
笔者小记:1、static关键字和constexpr关键字用法(static存在整个生命周期,外部文件禁止访问;constexpr在在编译时就已经计算出并且是常量,不能在程序运行时修改,即directions的值是固定的)。2、visited(row, vector(columns))被初始化为包含rows行,每行包含columns个布尔值的二维数组。3、vector(total)中vector容器初始化所有元素都会被默认为0,这与上面vector二维bool数组中的元素初始化为false一致。
2025-01-15 16:14:31
765
原创 编程题-字符串相加
笔者小记:1、string ans = ""初始化字符串时,可创建“”空2、三目运算符的使用可简化代码量3、当一个char类型值与一个int类型值相加或相减时,结果也会是其相应char类型字符,即ASCII码的相对运算(ASCII码也是int类型的)可简化代码操作,不会报错。例如,'a' + 1 = 'b'。4、对于std::string可以直接使用reverse()函数对string类型的字符串进行翻转,例如reverse(ans.begin(), ans.end()),得到的直接是ans翻转结果
2025-01-15 08:45:00
910
原创 编程题-移动零
使用双指针,左指针指向当前已经处理好的序列的尾部,右指针指向待处理序列的头部。右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。每次交换,都将左指针的零与右指针的非零数交换,且非零数的相对顺序并未改变。
2025-01-15 08:30:00
502
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人