LeetCode
Find Our Way
这个作者很懒,什么都没留下…
展开
-
Leecode279题——完全平方数
题目思路通过上面的树形图,正整数n可以分为某个完全平方数加上另外一个正整数,比如:12=1+11,或者12=4+8,12=9+3,我们设组成一个正整数最少的完全平方数为num[i],那么组成12的完全平方数最少平方数num[12]=min(num[11],num[8],num[3])+1,这样就会产生很多的子问题所以该题的动态规划方程为:设组成正整数n的最少完全平方数的个数为dp[n]...原创 2020-04-24 00:40:56 · 161 阅读 · 0 评论 -
组合总数
题目思路本题是给定一个正整数和数组,要求在数组中找出所有可以使数字和为该正整数的组合,其中数组中的数字可以重复使用如上图:可以看出,当我们的target值小于等于0时便停止搜寻,所以回溯递归的基准条件就是当target小于等于0。相关代码如下:class Solution {public: vector<vector<int>> res; vect...原创 2020-03-31 22:25:35 · 201 阅读 · 0 评论 -
解数独
题目思路首先我们先大概了解一下数独的相关要求:数字1-9只能在每一行中出现一次数字1-9只能在每一列中出现一次数字1-9只能在一个3*3的九宫格内出现一次通过解读数独的要求可知,我们要解决三个方面的问题:同一行的,同一列的,同一个3x3九宫格内的,根据回溯法的思想,我们可以设置三个二维数组,第一个维度表示:哪一行/列/九宫格,第二个维度表示该数字的使用情况,举个具体例子:ro...原创 2020-03-31 17:19:11 · 253 阅读 · 0 评论 -
括号生成
题目思路该题是属于回溯法类型的题目,题意是给出n代表要生成的括号数,求所有有效形式的括号组合首先我们先分析回溯递归的终止条件:比较直观的是括号数目达到了所给定的数目规定,但是一个括号会有左边和右边,如果不能很好的把握他们之间的顺序关系,那么就可能会造成输出不是有效形式的括号,那么我们如何把握保证输出的结果都是有效形式的呢?我们可以分别设置两个变量left,right分别表示目前所使用的左...原创 2020-03-31 16:32:50 · 118 阅读 · 0 评论 -
电话号码的字母组合
题目思路本题的难点之一是如何更好的将数字转换为相应的字母,一开始我的思路是使用hash,但是并不能很好的解决问题,如下图:从上图中我们可以知道,我们的目的就是要找出所有到达叶节点的路径,换句话说就是当到达树的深度时,我们便回头,很明显这是回溯法类型的题目。那么分析以下本题存在的难点和相关知识点:首先,相对于传统的回溯法类型的题目,本道题是一个数字代表三个或者四个字母,我们要避免选到同...原创 2020-03-28 00:35:48 · 232 阅读 · 0 评论 -
字符串相乘
题目思路题目给出两个字符串表示一个整数,要求这两个字符串代表的数字的乘积,并且他们的乘积也为字符串的形式,题目还限制了不能将这两个字符串直接转换为整数来处理。那么我们的思路是怎么样的呢,下面我们来看下面这个式子:整数123可以表示为: 123=1*10^2+2*10^1+3*10^0整数456可以表示为: 456=4*10^2+5*10^1+6*10^0那么:123*456=(1...原创 2020-03-18 01:42:01 · 626 阅读 · 0 评论 -
格雷编码
题目思路本题是给出一个代表位数的整数n,要求其格雷编码我们采用的是镜面对称的方法来求:设G(n)表示整数n的格雷编码集合,那么该集合的个数为G(n).size=2n(这里要解释一下,因为对于位数为n的二进制数,那么他能表示的最大整数为2n-1,但是我们要算上0,所以集合个数就为2n),同理G(n+1)的集合个数为2(n+1),我们可以发现,每当增加一位,那么格雷编码的集合数量就增加了一...原创 2020-03-19 00:47:19 · 150 阅读 · 0 评论 -
组合
题目思路题目的意思是给定两个整数n和k,返回数组[1……n]中所有可能的k个数的组合,那么我们可以画出树形图:从树形结构中我们可以知道,到达叶节点的条件就是树的高度等于k,每次我们都从选取节点的后面数组进行选择,这样能防止重复问题,相关代码如下:class Solution {public: vector<vector<int>> res; vect...原创 2020-03-16 22:46:39 · 99 阅读 · 0 评论 -
一和零
题目思路我们观察上图,画出树状图之后对于我们解题可能会清楚一点,从这张图我们能直观的看出来,对于m个0和n个1,它所能拼成最大的字符串数量应该就是各个子树所能拼成最大的字符串数量加上1。首先我们要明确的是dp表所表示的含义,这样才能更好的推出动态规划方程一开始我设置dp[i][j]表示i个0和j个1所能表示的最大字符串数量,但是动态规划方程却短路了,没有能推出来。分析自己的思路,首先确...原创 2020-03-15 22:41:45 · 153 阅读 · 0 评论 -
全排列II
题目思路本道题相比较上一道的全排序,多了一个重复的条件就是剪枝,因为序列中含有重复数字,所以可能会存在重复的序列,那么这时候就需要用到剪枝大体框架还是和上一道题类似,只是需要多一个去重的条件,那么我们可以发现,如果某个节点的取值的上一个是未使用的,并且该节点的关键字和上一个元素的关键字相同,那么就说明存在相同的分支,则需要将其剪掉(按照我的理解,剪掉就是跳过它,进行下一个遍历)按照回溯法的...原创 2020-03-05 23:05:34 · 170 阅读 · 0 评论 -
全排序
题目思路该题是给定一个没有重复数字的序列,返回所有的组合那么这题是属于典型的回溯算法,让我们回忆一下回溯算法:回溯算法其实有点类似与动态规划,不过也存在区别,动态规划是某个状态可以由前面的状态推出,而回溯算法则有点类似与穷举法,穷举所有的可能,尝试所有的可能,遇到走不下去的路就回头,通俗的来讲就是能向前走就一直向前走,走到头了就回头,回溯法实际上也算是一种深度优先遍历(dfs),当遍历到叶...原创 2020-03-05 21:56:14 · 120 阅读 · 0 评论 -
最大正方形
题目思路本道题有点类似寻找最大矩形,不过那题运用的是栈,这道题运用动态规划相对来说比较简单,那么这道题的思路是什么呢?先说说我一开始的思路:我设想是设置一个dp表,表示某个值为1的点作为正方形右下角时最大的矩形面积,但是这种想法最后证实不怎么好进行推进,也就是说比较难得出动态规划方程。后来我就想设置两个dp表,一个表示以该点为终点时高的最大值,一个表示以该点为终点时底边的最大值,然后在二者...原创 2020-03-01 22:45:24 · 162 阅读 · 0 评论 -
丑数II
题目思路本题要求我们求出第n个丑数,对于某个丑数,我们最直观的感觉就是该丑数是由前面的某个丑数x2或者x3或者x5而得,所以本题的难点就在于:如何通过以前所求的丑数求某个位置的丑数让我们首先按照动态规划的一般思路去思考:本题似乎是存在三个维度:x2的,x3的,x5的,那么如果我们设置三个dp数组,分别表示这三个维度,那么我们该如何推进状态呢,也就是说在设置这三个维度的情况下,如何求出状态转...原创 2020-02-28 01:18:49 · 141 阅读 · 0 评论 -
乘积最大子序列
题目思路本道题要求我们从一个找出乘积最大的连续子序列(该序列至少包含一个数)首先,必须要满足的条件是连续,那么相比较我们之前做的最大子序列和来说,本题存在的一个难点就是:一个最大的乘积的连续序列乘以一个负数后,就会变成最小的,同样,本来是最小的乘积的连续序列乘以一个负数后,有可能会变成最大的,如果参照最大子序列和一样只设置一个dp数组,dp[i]用来表示包含第i个元素的前i个元素的乘积最大的...原创 2020-02-28 00:03:59 · 929 阅读 · 0 评论 -
最佳买卖股票时期含冷冻期
题目思路首先分析题目,具体到每一天的状态有三个维度:买入,卖出,冷冻期,那么可以降为两个维度:持有股票和未持有股票,那么我们就设置两个dp数组,hold_dp[i]表示第i天持有股票的最大利益,nohold_dp[i]表示第i天不持有股票的最大利益持有股票有两种情况:(1)昨天就持有,今天不做任何操作,那么hold_dp[i]=hold_dp[i-1](2)前天卖出了,然后在今天买入股票...原创 2020-02-27 01:51:32 · 484 阅读 · 0 评论 -
买卖股票的最佳时期
题目思路动态规划:第i天的最大收益等于max(第i-1天的最大收益,第i天的价格-第i-1天范围内的最低价格)相关代码如下:class Solution {public: int maxProfit(vector<int>& prices) { if(prices.size()<2) return 0; ...原创 2020-02-25 17:10:31 · 128 阅读 · 0 评论 -
三角形最小路径和
题目思路本题是给定一个三角形,找出自顶向下的最小路径和,这道题是比较典型的动态规划类型的题目,但是该题的移动方式是只能移动到下一行中相邻的节点结点上,所以我们还是设置一个dp表,dp[i]表示某一行到达i节点的最小路径和,那么状态转移方程就为:dp[i]=min(dp[i-1],dp[i])+nums[i],需要注意的边界问题就是对于每一行的第一个节点,只能由dp[i]转换而来,而对于每一行...原创 2020-02-25 16:56:39 · 112 阅读 · 0 评论 -
打家劫舍II
题目思路该题相比较上一道题的打家劫舍来说,多了一个限制的条件,就是第一个房屋和最后一个房屋是相连在一起的,那么我们回顾一下上一道题的思路:我们设置一个dp表,dp[i]表示前i个房屋所能获取的最大利益,那么dp[i]=max(dp[i-1],dp[i-2]+nums[i]),如果加上这个限制条件,解题思路又是怎么样的呢?加上这个限制条件,最直接的说明就是第一家和最后一家不能同时偷,那么如何...原创 2020-02-25 16:42:32 · 132 阅读 · 0 评论 -
打家劫舍
题目思路首先我们来解读一下题目:我们将题目简介化就是:要求数组[o,n]范围内的元素最大和,且任意两个元素之间不能相邻首先讲一下大体思路吧:设置一个dp表,dp[i]表示[0,i]范围内所能获取的最大利益状态转移方程可得:dp[i]=max(dp[i-1],dp[i-2]+nums[i])其实这道题的思路也是挺简单的,就是设置一个dp表,但是一开始我是不怎么理解这个状态转移方程的...原创 2020-02-23 00:22:20 · 164 阅读 · 0 评论 -
爬楼梯
题目解题思路本道题是一道比较典型的动态规划题目,题目要我们求有几种方法可以到达楼顶,假设你每次只能走一个台阶或者两个台阶,那我们思路大概如下:设置一个dp表,dp[i]表示第i个台阶有多少种方法可以到达,我们可以列出状态转移方程:dp[i]=dp[i-1]+dp[i-2]边界的处理主要在当要爬的台阶小于2时所以相关代码如下:class Solution {public: ...原创 2020-02-22 23:51:02 · 128 阅读 · 0 评论 -
最小路径和
题目思路本题有点类似于杨辉三角形和不同路径问题本题是要求解一条路径,该路径上的数字之和最小。限制条件就是每次只能向下或者向右移动一步,那么我们如何使用动态规划解决本道题呢?我们还是设置一个dp表,dp[i]表示从左上角到本点i的最小数字总和。那么一个点i只能由它的左边或者上边走过来,那么我们就比较这两个方向的大小,选取最小的那个与i点的数字相加,用状态转移方程表示就是:dp[i]=min...原创 2020-02-22 17:46:26 · 126 阅读 · 0 评论 -
不同路径
题目思路思路一该题的一个思路就是直接使用公式,我们可以发现,走到终点所需走的总路程为m+n-2;那我们就在总路程里面选取向右走的顺序即可,相关代码如下: int uniquePaths(int m, int n) { int sum = m + n - 2; if (sum < 1) return 1; long long res = 1; in...原创 2020-02-22 17:34:54 · 116 阅读 · 0 评论 -
最大子序列和
题目思路分析问题我们按照动态规划的思路来解题首先判断该题目是否可以使用动态规划算法来解题。我们知道,可以使用动态规划的条件有:最优化原理:问题的最优解所包含的子问题的解也是最优的无后效性:某一阶段状态一旦确定,就不受这个状态以后决策的影响,即某状态以后的过程不会影响到以前的状态有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策可能被多次用到现在我们就来分析一...原创 2020-02-22 00:27:14 · 145 阅读 · 0 评论 -
摆动序列
题目思路首先理解一下什么是摆动序列,摆动序列就是两两之间的差是正数和负数交替,那么首先来分析一下该题的边界问题:第一个边界就是单个元素也属于摆动序列,第二个边界就是一个摆动序列只有两个元素(意味着他们的差为正数或者负数)那么我们的思路是什么呢,该题的标签为贪心算法的范畴,那我们如何从贪心算法入手呢?参考思路一既然要求最长摆动序列长度,那么我们就按照摆动序列的定义来,相比较上一次的差为正...原创 2020-02-19 22:59:39 · 1841 阅读 · 0 评论 -
根据身高重建队列
题目思路首先我们从一个最简单的例子出发,当队列中的(h,k)中的h都相同时,那么重新排序就按照k作为索引排序,例如:所以对于身高相同的情况,就按照人数k作为位置的索引。那么对于身高不同的情况是怎么样的呢,答案就是也是采用相同的策略,先将身高大的先插入,再将身高小的插入,两者都是按照人数k作为位置索引,因为身高大的看不见身高矮的,之前插入身高高的排序队列与我当前的插入过程无关例如:相...原创 2020-02-17 15:18:08 · 704 阅读 · 0 评论 -
跳跃游戏II
题目思路首先我们先明确:题目条件提示我们总是可以到达最后一个节点,那么该题与跳跃游戏之间有什么不同呢?首先本题已经假设我们总是可以到达最后一个点,所以我们不用再判断是否可以到达最后一个位置,其次,本题要求跳跃次数最少,那么我们如何从跳跃游戏的相关思路解决这道题呢?要求跳跃次数最少,那么本质上还是每次都要尽量跳最远,,那么我们如何选择跳跃策略呢?答案是:在范围内选择一个可以跳更远的点进行跳跃...原创 2020-02-16 15:24:32 · 130 阅读 · 0 评论 -
跳跃游戏
题目思路该题有两种思路解决思路一一种思路就是我们从左向右遍历,每次都选择跳最远的那个点,如果遍历到最远点之外的范围,则说明此时不能再往右遍历了,如果此时还没到达最右边的点,则说明不能到达,否则可以到达相关代码如下:bool canJump(vector<int>& nums) { //自左向右的遍历 int size = nums.size() - 1;...原创 2020-02-16 15:04:49 · 210 阅读 · 0 评论 -
加油站——贪心算法
题目思路自己的思路因为要找到出发点,那么最初的思路就是:设置一个变量,用于判断汽车是否能绕环一圈(因为加油总量和耗油总量如果为负数的话,那么说明是不能绕环一圈的)然后再设置一个变量用于表示油箱油量剩余,如果油箱油量加上加油量大于耗油量,那么说明能继续开往下一个点,否则从该点出发是不能到达下一个点的,则此时将油箱油量设置为0(说明该点不能作为出发点)我们再设置一个容器vector,将...原创 2020-02-16 14:44:25 · 591 阅读 · 1 评论 -
平衡二叉树
题目思路自顶向下我们知道一棵平衡二叉树定义为每个节点左右两个子树的高度差的绝对值不超过1,那么我们采用自顶向下的思路是:** 从根节点开始,比较该节点是否满足平衡二叉树的条件,然后再比较左子树和右子树是否满足平衡二叉树的条件,这是两个子问题,所以可以递归调用**相关代码如下:class Solution {public: bool isBalanced(TreeNode* ...原创 2020-02-12 15:50:45 · 108 阅读 · 0 评论 -
二叉树的层次遍历II
题目思路自己的思路就是采用队列进行存储,将每层的节点放在队列的头部,接着再将整个队列的元素赋值给vector容器,相关代码如下:class Solution {public: vector<vector<int>> levelOrderBottom(TreeNode* root) { vector<vector<int>&...原创 2020-02-11 20:30:42 · 146 阅读 · 0 评论 -
从前序/后序遍历与中序遍历构造二叉树
题目思路先知道一个定律:从前序/后序遍历+中序遍历可以确定一棵不存在相同节点的二叉树我们先复习一下深度优先的三个遍历:前序遍历:根节点——左子树——右子树中序遍历:左子树——根节点——右子树后序遍历:左子树——右子树——根节点所以当我们知道前序遍历和中序遍历后,大体思路如下:前序遍历的第一个为根节点接着我们去中序遍历中寻找根节点所在位置,那么根节点前面的就是左子树所有的节...原创 2020-02-11 20:26:26 · 213 阅读 · 0 评论 -
二叉树的层次遍历
题目思路二叉树的层次遍历有两种方法,分别是迭代法和递归法迭代法迭代法主要用到队列,将下一层的元素放到队列尾部,从队列首部弹出元素,代码如下class Solution {public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>...原创 2020-02-08 20:40:45 · 307 阅读 · 0 评论 -
相交链表
题目思路自己的思路——暴力解法分别遍历两个链表,记录下他们的长度s1,s2长链表先走|s1-s2|,然后短链表再以相同的速度出发当两个链表相等时,便是相交节点相关代码如下:class Solution {public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { i...原创 2020-02-08 16:41:46 · 222 阅读 · 0 评论 -
二叉树的最大深度
题目思路这道题采用递归很简单,直接上代码吧class Solution {public: int maxDepth(TreeNode* root) { if (root == NULL) return 0; if (!root->left && !root->right) return 1; return (max(...原创 2020-02-07 15:37:55 · 113 阅读 · 0 评论 -
对称二叉树
题目思路我们发现,一棵对称的二叉树具有以下特点:从根节点的左子树和右子树出发,左子树的左节点等于右子树的右节点,左子树的右节点等于右子树的左节点,即左 - 左=右 - 右,左 - 右=右 - 左,所以我们分别的递归比较这些节点代码如下:class Solution {public: bool isSymmetric(TreeNode* root) { if (root == ...原创 2020-02-07 15:19:02 · 127 阅读 · 0 评论 -
相同的树
题目思路采用先序遍历和递归相结合的方法解题,思路还是比较简单的class Solution {public: bool isSameTree(TreeNode* p, TreeNode* q) { if ((p && !q) || (!p && q))//如果两个数 相应位置节点数不相同,则直接返回false return f...原创 2020-02-07 14:19:50 · 103 阅读 · 0 评论 -
恢复二叉搜索树
题目思路首先来理解一下题目:一棵二叉搜索树中有两个节点被错误的交换,要求是恢复这颗二叉搜索树,那我们的思路要从哪里出发呢我们知道,中序遍历的结果是一个递增的关系,因为中序遍历一棵二叉搜索树的顺序为:左子树——根节点——右子树,所以大概思路就是我们中序遍历一棵二叉树,找到不是递增的地方我们还需要注意的是:交换的节点有两种情况:相邻节点之间的交换,比如中序遍历后[1,2,3,4,5]中...原创 2020-02-07 14:16:09 · 115 阅读 · 0 评论 -
不同的二叉搜索树
题目思路一开始也有想到对于任意一个值i,可以求出它左边范围内有多少种树的组合,右边范围有多少种树的组合,但无奈编程水平有限,不能很好的表达出来(我太菜了)相关代码如下:class Solution {public: vector<TreeNode*> generateTrees(int n) { vector<TreeNode*> v; if (...原创 2020-02-06 17:37:16 · 120 阅读 · 0 评论 -
验证二叉搜索树
题目思路自己的思路错误思路首先我们先分析一下题目,二叉搜索树就是左子树所有的节点都比根节点的关键值小,右子树所有节点的关键值都比根节点关键值大,一开始自己的思路就是利用递归,比较左子树根节点的关键值和根节点的关键值,和比较右子树根节点的关键值和根节点的关键值,然后再分别递归的判断左子树和右子树。相关代码如下:bool isValidBST(TreeNode* root) { //下...原创 2020-02-06 17:21:26 · 161 阅读 · 1 评论 -
逆波兰表达式求值
题目思路这道题相对来说是属于比较简单类型的了,思路也很简单,就是设置一个栈,然后遇到操作数就做压栈操作,遇到操作符就做出栈操作,然后再将结果压入栈中。说一下这道题一些知识点吧:将string转换为int:使用函数atoiswitch表达式中后面只能是整型或者字符型代码如下:class Solution {public: int evalRPN(vector<st...原创 2020-02-05 15:23:05 · 114 阅读 · 0 评论