LeetCode刷题
文章平均质量分 54
郑儿大人
努力成长的小青蛙
展开
-
【LeetCode120】-三角形最小路径和
实现思路动态规划中数据的表示含义: 第i行第j个元素到底层的最短路径求解: 是该元素相邻两个节点到底层距离+自己本身数值 取最小值如果从上到下计算,并不合理这样无法求解,且按照定义明显,最上层的元素应该是由下至上依次求解得到的实现代码class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { int dp[205][205]; for(原创 2021-05-21 13:08:41 · 65 阅读 · 0 评论 -
【LeetCode416】-分割等和子集
方法一(位运算)实现思路其实是一种几乎使用暴力求解的方法,但利用位运算进行了优化,用位运算中的0或1来代表集合中是否出现该元素,计算下集合中所有元素的和,如果和为总数量的一半,说明满足条件;之后再将满足条件的集合对应的值(并非相加计算的值),也就是代表集合中都有哪儿些元素的那个值,两两相或,如果两个相或的元素之间没有交集也就是相或结果为0的情况下满足条件。实现代码class Solution {public: int get_num(vector<int> &nums)原创 2021-04-10 16:36:49 · 83 阅读 · 0 评论 -
【LeetCode518】-零钱兑换 II
实现思路实现代码提交结果及分析时间复杂度O(n*amount),空间复杂度O(amount)原创 2021-04-10 13:49:29 · 67 阅读 · 0 评论 -
【LeetCode322】-零钱兑换
方法(动态规划)1.1实现思路利用之前的思路进行分析,首先分析DP数据代表的集合的含义,设置动态规划 的数组为DP,那么DP[i]代表的就是金额为i时使用的最少的钞票的数量,枚举所有和金额i有关系的钞票的金额,从中选择最小的那一个1.2实现代码class Solution {public: int coinChange(vector<int>& coins, int amount) { if(!amount) return 0; vec原创 2021-04-10 09:50:51 · 58 阅读 · 0 评论 -
【LeetCode198】-打家劫舍
方法一(DP)实现思路实现代码class Solution {public: int rob(vector<int>& nums) { if(!nums.size()) return 0; if(nums.size()==1) return nums[0]; vector<int> dp(nums.size()+1,0); dp[1]=nums[0]; dp[2]=max(nu原创 2021-04-07 16:02:31 · 68 阅读 · 0 评论 -
【LeetCode407】-接雨水 II
方法一实现思路实现思路,是基于【LeetCode42】-接雨水的思路,不同点在于不仅要考虑上下左右的最大值,同时也要考虑斜着的最大值最小值,针对每一个点,取这些最大值的最小值减去该点的高度值,就可以得到最终的结果实现代码(待补充)这个代码是有些不完善的,现在是只考虑上下左右的最大值,而没有考虑斜着的最大值,这种作法有待补充和优化class Solution {public: bool inner(int row,int column,int x,int y){ retur原创 2021-04-07 14:03:04 · 217 阅读 · 0 评论 -
【LeetCode473】-火柴拼正方形
实现思路实现代码提交结果及分析待改进代码:bool cmp(const int a,const int b){ return a>b;}class Solution {public: int sum_nums(vector<int> &nums){ int sum=0; for(int i:nums){ sum+=i; } return sum; }原创 2021-04-05 20:06:27 · 114 阅读 · 1 评论 -
【LeetCode126】-单词接龙 II
方法一实现思路实现代码const int maxn=5000+5;int path[maxn];void init(){ for(int i=0;i<maxn;i++){ path[i]=-1; }}class Solution {public: vector<string> getpath(bool flag,string beginWord,string endWord,vector<string>& word原创 2021-03-31 20:39:57 · 822 阅读 · 0 评论 -
【LeetCode127】-单词接龙
方法一实现思路主要思路是将字符串映射到来数字将问题抽象为求解最短路当两个单词之间只有一个字符不相同时就会有一条无向边求最短路的方法使用的dfs实现代码(超时)class Solution {public: int re; void dfs(vector<int> &book,vector<set<int>> &path,int start,int end,int step,int &re){ boo原创 2021-03-28 13:38:21 · 96 阅读 · 0 评论 -
【LeetCode200】-岛屿数量
方法一(DFS)实现思路思路是深度优先搜索+标记法需要额外开辟一个二维数组book来表明当前元素是否被遍历过,对每一可以构成岛屿遍历的结果使用flag来标记,不同的岛屿使用不同得到flag来标记,由于我设置flag是从-1然后依次递减的,所以最后的结果实际上就是flag数值的绝对值遍历整个原始的二维数组,每到一个点判断是否为土地且没有被划分到一个岛屿中,如果该土地没有被划分到一个土地中,就以该土地为起点作为一个新的岛屿来找其相邻的岛屿土地实现代码class Solution {private:原创 2021-03-27 11:01:11 · 54 阅读 · 0 评论 -
【LeetCode76】-最小覆盖子串
方法一实现思路实现思路是参照了【LeetCode3】-无重复字符的最长子串双指针+字符哈希1.首先统计所有匹配的子串出现的字符的种类及has_cnt数量,然后遍历许匹配的字符串2.同时在这个过程中记录当前的子串word,以及维护字符串s在这个过程中每个字符动态变化的数量cnt当cnt的数量大于has_cnt的时候,尝试移动begin————begin能移动的条件为cnt[begin]>has_cnt3.每次新产生的word子串都要判断一下是否满足条件且小于当前最短的子串结果判断子串满原创 2021-03-27 09:23:48 · 87 阅读 · 0 评论 -
【LeetCode187】-重复的DNA序列
方法一实现思路这种实际上是一种暴力求解的思想,从头到尾开始遍历所有长度为10的子串,在这个过程中利用map不断记录出现的子串的次数,最后遍历map中的结果,将统计的数目超过1的压入最终的字符数组中实现代码class Solution {public: vector<string> findRepeatedDnaSequences(string s) { map<string,int> cnt; vector<string>原创 2021-03-24 21:21:53 · 59 阅读 · 0 评论 -
【LeetCode3】-无重复字符的最长子串
实现思路优化至O(nlog(n))的算法,大部分是分治思想后者是二叉树的思想扫描整个字符串的一般还是考虑O(n)的时间复杂度实际上是要优化枚举在枚举的过程中存在很多不必要的枚举,当已经出现重复字符时就应该停止枚举双指针解决的思想只要满足begin是永远小于i,这个算法的时间复杂度一定是O(n)实现代码提交结果及分析...原创 2021-03-24 20:06:03 · 72 阅读 · 0 评论 -
【LeetCode49】-字母异位词分组
方法一实现思想由于每一个字符在字符串的排列组合是很多的,为了便于比较直接将每一个字符串内部进行排序,排完序之后再将整个字符串数组进行排序,在排序的时候需要记录自己原本的数组下标,然后依次遍历字符串数组,当排序后的字符串相同,就将原本字符串的形式压入相同的字符串数组中即可。实现代码bool cmp(const pair<string,int> &a,const pair<string,int> &b){ return a.first<b.first原创 2021-03-24 15:41:46 · 57 阅读 · 0 评论 -
【LeetCode290】-单词规律
实现思路利用map映射,将pattern中的字符映射到单词中,但实际上不仅要考虑这个映射,也要考虑单词映射到字符的情况,否则将无法识别:“abba”“dog dog dog dog”这种情况;除此之外,也要考虑,可能pattern中的字符个数和单词个数不匹配的问题我的思路是单词映射到字符,字符映射到单词保证两者是一一对应的关系,而另一种思路是使用unsed标志数组来看字符是否在之前已经别的单词映射了来判断。实现代码class Solution {public: bool word原创 2021-03-20 11:01:11 · 47 阅读 · 0 评论 -
【LeetCode409】-最长回文串
方法一实现思路主要利用了字符串哈希,将字符串对应的ASCII码作为下标来进行使用,先遍历字符串,统计字符串中每一种元素出现的次数。分情况讨论:偶数偶数的情况好考虑,直接将其数量添加到最长回文串的总数量上奇数奇数的情况要考虑,其实类似bbabb这样结构也是被允许的,说明在回文串中允许出现一个奇数,其他奇数再次出现时,只能保留其2的倍数个实现代码 bool cmp(const int a,const int b){ return a>b; }原创 2021-03-20 10:19:07 · 57 阅读 · 0 评论 -
【LeetCode70】-爬楼梯
方法一(暴力递归)实现思路原问题分解为子问题,子问题就是走一步还是走两步,走一步就多增加一种走法,走两步就增加两种走法实现代码一种遍历的写法void solve(int n){if(n== 1 || n==2){return n;}return solve(n-1)+solve(n-2);}这种情况下的写法之所以没有问题,原因是由于n的最小值一定是1,当为1的时候就会返回,不会出现无限循环的情况提交结果分析超时的原因:其实走每一步就是相当于有两种选择,要么走一步要么走两步,最终原创 2021-03-11 22:16:26 · 72 阅读 · 0 评论 -
【LeetCode449】-序列化和反序列化二叉搜索树
解码和复原的思考:其实只有前序的序列才可以实现,前序的情况第一个是根节点,所以才方便以此为开端建树实现思路字符串转换为二叉树(1)先将所有字符串按逗号分隔出整数(2)再利用整数新new节点,将所有的节点都存储在vector中可以发现题中给出的序列是前序遍历,也就是意味着第一个为根节点,遍历vector中除根节点以外的节点依次开始建树二叉树转换为字符串(1)实现将大于等于1位的整数转换为字符串(2)转换之前先拼接[(3)转换之后再拼接](4)中间过程记得除了第一位,都在前面加上,此过原创 2021-03-10 19:31:56 · 82 阅读 · 0 评论 -
【LeetCode33】-搜索旋转排序数组
方法一实现思路(一)先遍历数据,如果数据一直单调递增就计数+1,直到第一个不递增的数停止,利用这种方法就可以知道未被翻转的原数据的头部下标t(二)然后将给出的翻转数据排序,然后利用二分查找找出元素是否出现在该数组中,如果在获取下标,因为该数据经过了重新排序,所以我们需要将该数据转换成翻转数据的下标index,转换公式:(index+t)%nums.size()总体思路是不破坏二分查找的结构,而将注意力转移到二分查找之后的数据上实现代码class Solution {public: i原创 2021-03-09 09:17:03 · 48 阅读 · 0 评论 -
【LeetCode34】-在排序数组中查找元素的第一个和最后一个位置
方法一实现思路由于在本题中有重复元素的存在,不能直接使用二分查找先使用map统计了下每一个元素出现的次数,然后利用set构造了没有重复元素的vector数组,在该数组中进行二分查找,当查找到该元素后,利用map数组中存储的数据,实际计算出数据出现的范围,然后返回结果;当没有找到时,直接返回[-1,-1]主要思想是二分查找框架上的小拓展实现代码class Solution {private: map<int,int> cnt;public: void get_beg原创 2021-03-08 22:17:29 · 46 阅读 · 0 评论 -
【LeetCode35】-搜索插入位置
实现思路使用二分查找,利用二分查找循环代码的框架具体可参照【刷题基础知识】-二分查找与普通的二分查找不一样的点主要在于这里面不仅要判断是否存在元素,如果找到了该元素要直接返回该位置,如果没有找到要返回该元素正确应该在的位置。情况可以主要分为两大类第一类:找到了该元素,直接返回该元素的下标第二类:没有找到该元素,需要再分两种情况(1)target比终止状态大在正常的比较中,这个target最后一步是和1比较可以发现target比1大此时begin=0,end=0,按照算法begin=m原创 2021-03-08 21:42:31 · 56 阅读 · 0 评论 -
【LeetCode207】-课程表
方法一(DFS)实现思路将所有的关系抽象为有向图,图的结点代表的是课程,有向边代表的是两者之间的先后关系核心思想: DFS+访问状态访问状态的设置:(1)-1代表没有访问(2)0代表当前正在访问的结点(3)1代表已经访问过大体步骤:(一)初始化,初始化所有结点的初始访问状态为-1,建立邻接表(二)遍历所有尚未访问的点进行DFS,此时如果DFS返回false代表有环,否则都遍历完返回trueDFS的核心逻辑DFS初始时标记当前的结点状态为0,遍历完所有邻居结点后状态设置为-1在遍历邻原创 2021-03-03 22:10:27 · 148 阅读 · 2 评论 -
【LeetCode199】-二叉树的右视图
实现思路总体思路是要压入节点及层数,层数其实就是该节点的父节点的层数+1实现代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : v原创 2021-03-03 14:59:11 · 78 阅读 · 2 评论 -
【LeetCode114】-二叉树展开为链表
二叉树遍历结合求解的思路:总体上都是用递归来实现前序:进入递归在做的一些操作中序:左子树递归完成之后的操作后续:右子树递归完成之后的操作方法一实现思想实现代码方法二实现思路在不开辟额外的空间的情况下,完成题目要求实现代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; *原创 2021-03-03 12:41:17 · 60 阅读 · 0 评论 -
【LeetCode236】-二叉树的最近公共祖先
实现思路先求出到达两个结点分别的路径,将路径存储起来实现代码自己实现的代码一:(超出内存限制)实现代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */cl原创 2021-03-03 10:06:49 · 51 阅读 · 0 评论 -
【LeetCode113】-路径总和
实现思路对树进行前序遍历,在遍历过程中,保存路径和累加和,当遍历到根结点时也就是左右结点为nullptr的点时,判断加上该结点的sum是否和targetNum相等,如果相等将路径保存到结果的vector中实现代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : v原创 2021-03-03 08:55:36 · 46 阅读 · 0 评论 -
【LeetCode10】-正则表达式匹配
方法一(递归)实现思路递归求解的本质就是在于遍历所有递归状态节点,寻找问题的解上述文字及我自己梳理画出的思维导图,描述了匹配的三种方式。其实递归每走到一步,都要尝试下这三种匹配方式。最终尝试得到是否匹配的结果。匹配成功条件:匹配规则已经用空了,s也变成了空利用了DFS的思想内核,就是每到一个状态遍历我能走的所有下一步,在这些尝试中得到结果。这道题里面的三种匹配方式就是我能走的“三种步”。TIP: 现阶段我理解DFS(递归)的关键:递归出口,当前状态能遍历的步(有的还涉及回溯【也叫状态重置】的修原创 2021-02-18 15:37:53 · 74 阅读 · 0 评论 -
【LeetCode46】-全排列
理论知识状态变量可以用来标识我们所处的阶段其中的布尔数组used就是典型的空间换时间回溯算法中的回溯就是状态重置一般递归算法的时间复杂度和递归树中的叶节点个数有关方法一实现思想使用递归的方法实现,在递归的过程中额外使用book的map数组标识该数是否已经被使用过,没有使用过就使用然后往下构造,这个一直往下构造完最终结束回来的时候,要将标志恢复到初始状态递归的出口:构造的数组大小等于原数组的大小,将构造的数组压入结果数组中实现代码class Solution {private:原创 2021-02-17 20:27:12 · 63 阅读 · 0 评论 -
【LeetCode17】-电话号码的字母组合
方法一(DFS)实现思路提前存储按钮对应的字母信息利用递归的方法,在每一层依次遍历按钮对应的所有字母递归出口:当组合的字符串长度等于按号长度时,将组成的字符串压入结果数组中代码实现中:不同按钮对应的字母个数是不同的,所以将按钮的字母数据统计存储到了vector中,便于在递归的过程中可以统一使用.size()获取字母的种类个数实现代码class Solution {public: void generate(int i,string s,string digits,vector<原创 2021-02-17 20:17:07 · 79 阅读 · 0 评论 -
【LeetCode315】-计算右侧小于当前元素的个数
方法一(归并)实现思想分析如果使用暴力求解的方式,需要每一个元素从左到右一次遍历统计自己右侧比自己小的个数,时间复杂度为O(n^2)但其实在这个过程中有些比较时冗余的,以5,8,3为例,3比8小被计数,那么在统计8的时候8明显比5大,且3又在8的右侧也要被计数,但是相当于多比较了一回。概括来说,满足在右侧的条件下,一个数比该数小,肯定也比大于该数的数小。归并思想【刷题基础知识】-归并排序套用归并的框架,主要修改归并代码不修改排序的代码;i记录左侧数组遍历下标j记录右侧数组遍历下标(j其实就原创 2021-02-17 14:11:41 · 1311 阅读 · 0 评论 -
【LeetCode51】-N皇后
方法一实现思路首先理解一个皇后的攻击范围(以四皇后为例,红色箭头为皇后攻击范围)在攻击范围内的格子是不能放别的皇后的放皇后的思路:一、 遍历每一行,在每一行中特定列中放置皇后这么遍历的好处是肯定保证了同一行中只有一个皇后,将问题转换为了选择不发生冲突的列二、 在没有可以选择的列中放置皇后这里可以选择的列要满足两个条件:本列之前没有放过皇后放在此行此列(x,y)不在其他皇后(xi,yi)的对角线上两个位置(x1,y1),(x2,y2)在同一个斜线满足的条件为abs(x1-x2)=原创 2021-02-16 19:27:04 · 207 阅读 · 0 评论 -
【LeetCode22】-括号生成
实现思路实现代码class Solution {public:void generate(string s,int l,int r,int n,vector &re){if(l>n||r>n) return;if(ln&&rn){re.push_back(s);return;}generate(s+’(’,l+1,r,n,re);if(l>r)generate(s+’)’,l,r+1,n,re);}vector generatePare原创 2021-02-16 14:50:59 · 49 阅读 · 0 评论 -
【LeetCode40】- 组合总和 II
方法一(回溯+剪枝)实现思路实现代码class Solution {public: void generate(int i,int sum,vector<int> item,vector<int> &nums,vector<vector<int>> &re,set<vector<int>> &re_set,int target){ if(i>=nums.size()||s原创 2021-02-15 22:16:36 · 63 阅读 · 0 评论 -
【LeetCode90】-子集 II
方法一实现思路实现代码class Solution {public: void generate(int i,vector<int> item,vector<int> &nums,set<vector<int>> &res){ if(i>=nums.size()) return; item.push_back(nums[i]); if(!res.count(item))原创 2021-02-15 11:44:28 · 43 阅读 · 0 评论 -
【LeetCode78】-子集
方法一(回溯法)实现思路主要就是考虑一个元素还是不放的问题,虽说是回溯的方法但实际上就是暴力的枚举注意:不要忘记空集也是子集实现代码class Solution {public: void generate(int i,vector<int> item,vector<int>&nums, vector<vector<int>>&re){ if(i>=nums.size()) return;原创 2021-02-15 10:31:24 · 42 阅读 · 0 评论 -
【LeetCode435】-无重叠区间
实现思路贪心的思想在于,如果两区间没有交集则正常更新区间的end,如果两区间有交集end取两区间的最小值,消除区间的个数+1,这么做可以使得满足不重叠的条件但又为下面区间不重叠留出了更大的范围实现代码bool cmp(const vector<int> &a,const vector<int> &b){ return a[0]<b[0] ||(a[0]==b[0]&&a[1]<b[1]);}class Solution {原创 2021-02-13 19:55:05 · 44 阅读 · 0 评论 -
【LeetCode605】-种花问题
方法一实现思路就是尽量靠最左边或靠最优边种花,如果不可行尽量在前面只隔一个种花实现代码class Solution {public: bool canPlaceFlowers(vector<int>& flowerbed, int n) { if(flowerbed.size()==1&&!flowerbed[0]&&n<=1) return true; for(int i=1;i<flower原创 2021-02-13 18:28:16 · 113 阅读 · 0 评论 -
【LeetCode763】-划分字母区间
方法一实现思想首先要理解子片段是怎么定义的,子片段保证里面含有的字母仅出现在该子片段中,也就是不同子片段之间字母是没有交集的利用了【LeetCode392】-判断子序列拓展题目的思想,提前存储了字符串中各个字母出现的初位置和末位置利用了 【LeetCode452】-用最少数量的箭引爆气球 不同区间更换弓箭手的思想,当两个区间有重叠时,更新区间,当两个区间没有重叠时,将当前结果压入,更新区间的范围为新区间的范围概括来说就是遍历求得每一种字母在字符串中起始结束位置,按照起始位置将数据升序排列,遍历该预原创 2021-02-13 15:22:44 · 57 阅读 · 0 评论 -
【LeetCode122】-买卖股票的最佳时机 II
方法一这题是在 【LeetCode121】买卖股票的时机基础上的一道题目实现思路实现思路只要两天股票差值大于0即可买入和卖出得到利润,所以将所有两天利润大于0的值累加即可得到最大利润实现代码class Solution {public: int maxProfit(vector<int>& prices) { int n=prices.size(); vector<int> sub; int max=0;原创 2021-02-13 11:15:38 · 59 阅读 · 0 评论 -
【LeetCode121】-买卖股票的时机
实现思路存储了pmin数组,pmin[i]代表从0到i的最小值存储了pmax数组,pmax[i]代表从i到n-1的最大值以i为分界点,计算(i-1到n的最大值)- (0到i的最小值),取这些差值的最大值作为结果实现代码class Solution {public: int maxProfit(vector<int>& prices) { int n=prices.size(); int max=0; vector<原创 2021-02-13 10:53:50 · 57 阅读 · 0 评论