- 博客(45)
- 问答 (3)
- 收藏
- 关注
原创 从零开始的CPP(39)——回溯与跳过重复元素
依然是跳过重复元素,但是需要增加条件:前一项没用过。如果不这样添加条件,就会无法添加元素。给定一个可包含重复数字的序列。返回所有不重复的全排列。
2024-08-11 16:47:35 234
原创 从零开始的CPP(38)——递归与动态规划
递推条件:没使用过的,push进temp。递归达到最大深度后,释放最后一位。回溯都是一位一位释放的,不要着急。递归终止条件:temp达到预定大小,push,返回。需要记忆nums是否被用过,使用used记忆。给定一个不含重复数字的数组。
2024-08-11 13:02:58 199
原创 从零开始的CPP(37)跳跃游戏,动态规划,贪心算法
leetcode45给定一个长度为 的 0 索引整数数组 。初始位置为 。每个元素 表示从索引 向前跳转的最大长度。换句话说,如果你在 处,你可以跳转到任意 处:返回到达 的最小跳跃次数。生成的测试用例可以到达 。示例 1:输入: nums = [2,3,1,1,4]输出: 2解释: 跳到最后一个位置的最小跳跃数是 。 从下标为 0 跳到下标为 1 的位置,跳步,然后跳步到达数组的最后一个位置。我最开始用递归解决时间复杂度高,无法通过。于是使用动态规划。动态规划
2024-08-10 11:21:16 444
原创 从零开始的CPP(36)——操作Excel
现有一个Excel A1.csv。其表格第一列为:生物样本的名称;其他列为:生物样本的含量。表格第一行第一列是空格,第一行其他列为:受试者名称。
2024-08-09 12:30:04 463
原创 从零开始的CPP(35)——字符串乘法
按照乘法的计算流程,先算字符串末尾的,存入vector末尾,有进位就存入上一位。简单题里有过让自己写乘法的题目,当时只需要使用几个temp中间变量储存进位信息就行了。所以我们不使用数值类型的temp储存进位,而使用vector储存运算的中间结果。对于普通题目,如果代码越改越复杂,那么多半是思路错了,重新理清思路就好了。不能使用任何内置的 BigInteger 库或直接将输入转换为整数。中等题肯定不能这么做了,因为测试用例的数都很大,这种解法不能通过。的乘积,它们的乘积也表示为字符串形式。
2024-08-04 13:09:31 231
原创 从零开始的CPP(34)如何处理“重复元素且解集不能包含重复的组合”问题
40随着数组中重复元素越来越多,必须有一种方法排除所有重复的。也就是对于1 1 1 1,只有第一个1传入递归,其他的自动skip。这个问题以前也遇见过(在一个双指针题里),处理方法就是i>start_index,并且i=i--的值时,skip,就可以轻松解决。这个题和上一个题的区别:39允许一个数使用多次,40一个数只能用一次。39和40都不能有重复解,但是39很容易解决,回溯写出来就不会有重复的。中的每个数字在每个组合中只能使用。给定一个候选人编号的集合。解集不能包含重复的组合。中所有可以使数字和为。
2024-08-03 14:07:18 230
原创 从零开始的CPP(33)多种终止条件的回溯
回溯本质是深度优先搜索,可以看图来解释。不符合要求(sum>target)就弹栈(temp.pop_back),符合要求(sum=target)就把temp存入res再弹栈。为了防止重复搜索,设置一个k,保证只搜索索引>=当前索引的,不会搜索之前搜索过的。这道题要使用回溯来解决,之前说过,回溯只需要搞清楚终止条件(防止一直递归下去)和递推条件就行。2 和 3 可以形成一组候选,2 + 2 + 3 = 7。如果至少一个数字的被选数量不同,则两种组合是不同的。7 也是一个候选, 7 = 7。
2024-08-03 11:09:46 188
原创 从零开始的CPP(32)二分查找
{5,7,8,8,8,10}, 最开始的mid是在中间的8,那我应该如何控制下一步指针的移动方向呢?无论是向左还是向右,都只能求得一个边界。所以单个二分查找很难解决问题,但是使用两个二分查找,分别负责两个边界,就很轻松的解决了。最开始我以为答案要返回所有目标值的位置,就写了很麻烦的搜索方法,并用set存储所有位置,然后发现不符合题目要求,于是重写。一开始我有一个很疑惑的点, 比如。请你找出给定目标值在数组中的开始位置和结束位置。重写的方法使用递归,涉及到重复搜索,时间复杂度高。如果数组中不存在目标值。
2024-07-31 15:59:45 165
原创 从零开始的CPP(31)——位运算,三元条件运算符
之后进入迭代,不断减b*2,能减的话商加2,减不了商加1,商在每次迭代中只会是1或者2。直到b>a,迭代终止。思路就是一直迭代,迭代的过程中减小被除数。直到被除数小于除数,停止迭代。代码里使用了异或运算^来判断被除数与除数是否同号,使用三元条件运算符。10/3 = 3.33333.. ,向零截断后得到 3。所以同号时,condition是0,返回1,异号返回-1。整数除法应该向零截断,也就是截去(有符号整数,其数值范围是。乘法、除法和取余运算。这个题其实就是让你整除。给你两个整数,被除数。
2024-07-29 23:53:34 360
原创 从零开始的CPP(30)又是双指针
返回的数组里可以有重复的数,比如[2 2 2 2],但不能有两个[2 2 2 2],我以前的做法就是在添加数组时不考虑,都添加完后,利用set的唯一性一口气删除重复数组。这样可以避免有重复解。如果设置nums[i]==nums[i+1]就continue,这是错的,因为答案里包括[2 2 2 2]这种数组内部有重复数字的。这样移动左右指针时,单靠r>l这一个条件,根本无法保证r≠i与l≠i,只能在循环里额外添加很多臃肿的判断。l设置在i j等变量的右侧,这样仅需r>l这一个条件,就能保证r≠i与l≠i。
2024-07-24 17:22:40 361
原创 从零开始的CPP(29)回溯算法
写递归代码不需要细想,只需要明确:1.何时终止递归 return 2.递归下一层与当前层的关系。搞清楚这两点,我们只需要看一条树枝就够了。循环无法解决四个数字及以上的情况,需要递归。因为0和1不对应字母,我们先删除字符串中的0和1。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。2.下一层会增加一个字母,这个字母来源于phoneMap中的一个。1.当指针index走到尽头时,递归终结,储存result。的字符串,返回所有它能表示的字母组合。
2024-07-24 15:12:18 449
原创 从零开始的CPP(28)——双指针+条件判断
与 target 最接近的和是 2 (-1 + 2 + 1 = 2)。在操控双指针不断逼近target的同时,也要打擂台,记录最优的sum。中选出三个整数,使它们的和与。假定每组输入只存在恰好一个解。
2024-07-23 18:09:53 211
原创 从零开始的CPP(27)——双指针遍历
不同的三元组是 [-1,0,1] 和 [-1,-1,2]。最开始决定用map提前储存一些结果,把三层循环变成双层循环。写的很糙,还需要用set剔除一下,不过总算是合格了。注意,输出的顺序和三元组的顺序并不重要。答案中不可以包含重复的三元组。结果第三步执行时间太长,不行。,判断是否存在三元组。
2024-07-23 16:03:38 212
原创 从零开始的CPP(26)映射表储存对应关系解决整数——罗马数转换问题
罗马数字是通过添加从最高到最低的小数位值的转换而形成的。3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)700 = DCC 由于 500 (D) + 100 (C) + 100 (C)注意:49 不是 50 (L) 减 1 (I) 因为转换是基于小数位。40 = XL 由于 50 (L) 减 10 (X)9 = IX 由于 10 (X) 减 1 (I)不过这样写太乱了,就用映射表换成了更简洁的写法。当然,这变成了双循环,运行速度变慢了。最开始用了暴力枚举法。
2024-07-22 15:43:24 250
原创 从零开始的CPP(25)双指针遍历
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。所以用双指针,从两侧向内循环。每次循环移动高度低的指针。轴共同构成的容器可以容纳最多的水。找出其中的两条线,使得它们与。返回容器可以储存的最大水量。本来用双循环,但是超时了。
2024-07-22 14:40:30 204
原创 从零开始的CPP(24)异常捕获try catch
当数值过大时,stoi无法执行,所以要把stoi放进try中,如果有异常,就不执行,直接返回0。使用try catch ,即使出现异常,也不会影响后面程序的执行。如果反转后整数超过 32 位的有符号整数的范围。给你一个 32 位的有符号整数。中的数字部分反转后的结果。
2024-07-21 10:09:28 183
原创 从零开始的CPP(23)动态规划解决最长回文串
最开始我是将回文串都存入map。使用substr进行切割,i为起始,j-i+1是步长。"aba" 同样是符合题意的答案。优化了一下,还是时间复杂度高。最终还是用动态规划的方式解决。的子串是一个回文串;是一个二维数组,其中。
2024-07-20 11:11:18 286
原创 从零开始的CPP(22)使用map+vector+set查找无重复字符串的最长长度
这里将无重复字符串的长度都存入set,利用set升序排序的特性,最后利用迭代器返回最大值。因为begin迭代器指向起始值,end迭代器指向最后值的下一位,所以需要向前移位--,请你找出其中不含有重复字符的。因为无重复字符的最长子串是。也可以用打擂台的思想返回最大值。,所以其长度为 3。
2024-07-19 16:10:23 232
原创 从零开始的CPP(21)——链表与字符串/向量的转换&字符串与整数的转换
这是转换成字符串的做法,再用stoll把字符串变成数再相加。当然,因为long long也有长度限制,很多过长的测试用例是无法通过的。这是转换成向量再对向量进行相加的做法,也不会受到长度的限制。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。的链表,表示两个非负的整数。它们每位数字都是按照。请你将两个数相加,并以相同形式返回一个表示和的链表。的方式存储的,并且每个节点只能存储。突发奇想想折腾成字符串/向量去做。(两种做法都很没必要。
2024-07-19 14:44:26 260
原创 从零开始的CPP(20)——创建链表,输出链表,删除链表
在C++中,如果两个指针指向同一个对象(在此上下文中,是链表中的节点),改变通过一个指针所进行的操作会影响到另一个指针看到的内容,因为它们实际上是共享同一块内存的。prev=prev->next/prev=curr只对指针移位,不改变链表。通过影响指针的指向(prev->next),就可以改变链表的内容。prev->next=curr改变了指针指向,所以会改变链表。,请你删除链表中所有满足。给出了创建节点的两种方法。给你一个链表的头节点。
2024-07-18 15:04:10 196
原创 从零开始的CPP(19)——寻找最小山形三元组
实现思路很简单,但是时间复杂度是O(n^2),会超出时间限制。如果不存在满足条件的三元组,返回。满足下述全部条件,则认为它是一个。题目源自于leetcode周赛。的山形三元组,并返回其。所以只能用单层循环实现。
2024-07-18 14:20:34 124
原创 从零开始的CPP(18)—— 需要声明vector内存的情景
和result[i].resize(l);但是这里需要注意,因为直接访问了vector的角标,所以必须要预先分配大小,否则会报错。在「杨辉三角」中,每个数是它左上方和右上方的数的和。题目源自于leetcode118 杨辉三角。该题目是一道简单的动态规划题,解决思路参考。生成「杨辉三角」的前 numRows。给定一个非负整数 numRows。
2023-12-06 11:07:25 381 1
原创 从零开始的CPP(17)—— 递归中的“存档”
每轮递归都有自己的sum,像是一个存档,所以可以保证sum里总是由root延伸下来的。bool递归return false就是返回,return true就是继续。最开始我用了&sum,导致一轮递归结束后root处的值丢失了,不好处理。的路径,这条路径上所有节点值相加等于目标和。也可以用void写帮助函数,需要有额外的定义。题目来自于leetcode112 路径总和。和一个表示目标和的整数。是指没有子节点的节点。
2023-12-05 16:18:51 408
原创 从零开始的CPP(16)——平衡二叉树的判断
这是一种倒序的遍历方法,先从末尾的节点判断,当前节点的r与l都源自于它的叶子结点。③传入4node的左侧,但是直接return,h=0,所以4node的l仍为0。这是一种自下而上判断平衡的方法,因为肯定是最下面的节点最先跑完递归全程。3node进入root->right递归,不改变3的r,仍为0。2node进入root->right递归,不改变的r,仍为0。以这棵树为例,我们快进到4node进入递归的情景,3node平衡,返回h=1+1=2,也就是2的l。的左右两个子树的高度差的绝对值不超过 1。
2023-12-03 15:01:04 70
原创 从零开始的CPP(15)—— BFS广度优先搜索
前几篇博客用的都是dfs,即优先考虑深度。而bfs则是优先考虑当前层级上的节点,而不是深入到下一层级。Breadth就是宽度。是指从根节点到最远叶子节点的最长路径上的节点数。题目源自于leetcode104 二叉树最大深度。bfs可以借用vector实现。
2023-11-30 10:44:22 78
原创 从零开始的CPP(14)——迭代遍历对称二叉树,continue
之后的所有代码,并开始下一轮循环。这使得后续的弹栈可以正常进行,而不是一直存入空节点。帮助函数也可以用void写,但是需要控制一个量id表示对错。题目源自于leetcode101。这里用了continue,给你一个二叉树的根节点。, 检查它是否轴对称。这里用栈来储存树的节点。会跳过当前循环迭代内。
2023-11-29 10:13:58 57 1
原创 从零开始的CPP(13)——用迭代与递归两种方法进行二叉树中序遍历
题目源自于leetcode 94 二叉树的中序遍历给定一个二叉树的根节点root,返回它的遍历。中序遍历(Inorder Traversal)是二叉树遍历的一种方式,其中每个节点的左子树先被访问,然后访问节点本身,最后是右子树。在中序遍历的过程中,节点的访问顺序是按照左子树、根节点、右子树的顺序进行的。该二叉树的中序遍历结果为:4, 2, 5, 1, 6, 3, 7。
2023-11-26 20:24:08 87 1
原创 从零开始的CPP——(12)冒泡排序,选择排序,插入排序
题目源自于leetcode 88合并两个数组给你两个按排列的整数数组nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你nums2到nums1中,使合并后的数组同样按排列。最终,合并后数组不应由函数返回,而是存储在数组nums1中。为了应对这种情况,nums1的初始长度为m + n,其中前m个元素表示应合并的元素,后n个元素为0,应忽略。nums2的长度为n。需要合并 [1,2,3] 和 [2,5,6]。合并结果是 [,2,
2023-11-25 14:20:47 67
原创 从零开始的CPP(11)——删除链表元素
然后还需要删除掉cur->next防止内存泄漏,这里需要先定义一个temp存住cur->next,再对cur->next进行上述移位处理,再删除掉temp,也就删除了它指向的cur->next。如何删除呢,只需要把cur->next变成cur->next->next,这样cur就会指向cur->next->next而不是cur->next啦。解决思路很简单,只要链表指向不为空就遍历,如果检测到重复就删除,反之就继续。题目来自于leetcode 83题。给定一个已排序的链表的头。
2023-11-24 19:37:00 57 1
原创 从零开始的CPP(10)——动态规划(爬楼梯)
1.找到dp[n]的表达式,即状态转移方程,本题中dp[n]=dp[n-1]+dp[n-2]。因为你走出最后一步到达第n层的方式只有两种,一种是从n-1层爬上去(此时爬到第n层的方法实际是dp[n-1]种),一种是是从n-2层爬上去(此时爬到第n层的方法实际是dp[n-2]种),而因为层数不同,所以dp[n-1]种和dp[n-2]种的方法里不可能有重复的(重复的走法走不到不同的层数)。定义爬到n层的方法有dp[n]种,首先明确随着n的上升,dp[n]一定是跟着上升的,当需要计算方案数量时。
2023-11-23 13:25:26 69
原创 从零开始的CPP(9)——二分法查找/不同的数据类型
题目源自于leetcode 69给你一个非负整数x,计算并返回x的。由于返回类型是整数,结果只保留,小数部分将被不允许使用任何内置指数函数和算符,例如或者x ** 0.5。x = 828 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。使用二分查找的情景:范围上下界(left和right)大致已知,需要查找因为判断语句是l<=r,所以返回r是小于且最接近结果的,返回l是大于且最接近结果的。本题要求只返回整数部分,所以返回r。
2023-11-19 13:53:30 106 1
原创 从零开始的CPP(8)—— 字符串相加
会将字符 '0' 到 '9' 映射为整数 0 到 9,因为在ASCII编码中,数字字符 '0' 到 '9' 的ASCII码是连续的。如果a[i] b[i] carry和为2,说明c[i]=0,且要用carry进位,实际就是%2与/2。而a[i] + b[i] == 0是字符相加,得到的是它们对应ASCII码的和。为了方便处理,反转字符串。这是一种常见的将字符表示的数字转换为实际整数值的方法。,以二进制字符串的形式返回它们的和。题目源自于leetcode66。是字符 '5',那么。给你两个二进制字符串。
2023-11-18 10:48:30 77 1
原创 从零开始的CPP(6)——动态链表,结构体指针,指针引用
题目背景来源于leetcode21题合并两个有序链表。将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
2023-11-13 21:36:16 87
原创 从零开始的Linux(5)ubuntu18.04下运行VINS-Mono/VINS-RGBD(保姆级超级详细教程)
这里记录了我安装运行vins-rgbd踩的很多坑,希望能帮到你。
2023-10-30 17:39:01 1303 3
原创 从零开始的Linux(4)ubuntu安装第三方库(无需git clone)
最近配置orb slam的环境,涉及到下载很多第三方库,网上很多都用git clone的方法,但是我的网络不好,用网上的改进方法也不好用,报错:fatal: unable to access ‘https://github.com/...‘最后还是选择在windows下下载源码,以安装opencv为例,直接在windows下进入。之后把文件夹复制到ubuntu下就可以啦,之后就可以在ubuntu正常进行编译了。进入opencv目录,创建build文件夹,进入build,打开终端,输入。
2023-10-14 17:13:50 224 1
原创 从零开始的Linux(3)ubuntu16.04安装Pangolin
进入build目录,进入example,进入HelloPangolin目录,打开终端,输入./ HelloPangolin执行可执行文件,看到如下界面说明成功。回到build目录,删除掉里面所有文件,重新进行一次cmake流程,重新执行HelloPangolin,即可成功。需要注意, 目前github上的pangolin为高版本,在ubuntu16.04下编译安装会报错!之后进入Pangolin根目录,在Pangolin目录下创建build目录,进入build目录。在build目录下打开终端,
2023-10-13 15:29:03 836 1
原创 从零开始的Linux(2)在Kdevelop中运行工程
和在终端使用cmake指令类似,但是我们可以使用kdevelop省去cmake ..与make的过程。
2023-10-09 13:22:35 672 1
原创 从零开始的Linux/CPP(1)g++与cmake,argc与argv,静态库动态库,宏定义,头文件与源文件
是一个常见的用法,用于在头文件中进行重复引用的防护。当一个头文件被多个源文件引用时,如果没有适当的防护措施,可能会引发重定义错误。这意味着同一个符号(变量、函数、类等)在多个源文件中被定义了多次,编译器无法确定使用哪个定义,从而导致错误。为了解决这个问题,可以在头文件的开头使用条件编译指令。#ifndef表示 "if not defined",检查一个宏是否被定义。#define用于定义该宏,以便防护代码仅被编译一次。如果宏没有被定义(即之前没有被包含过),则继续编译下面的代码。在宏。
2023-10-08 21:59:29 185 1
空空如也
链表拼接时原链表被意外改变(leetcode21题)
2023-11-13
visual studio无法生成解决方案
2022-12-07
pygame飞机大战碰撞检测失灵
2022-04-13
pygame飞机大战碰撞检测失灵
2022-04-13
pygame开发飞机大战中的键盘监听问题
2022-04-12
TA创建的收藏夹 TA关注的收藏夹
TA关注的人