leetcode
Lzed
我好菜啊
展开
-
<Leetcode> 1. Two Sum
题目链接https://leetcode.com/problems/two-sum/思路用unordered_map将序列hash,然后对于每个数,O(1)的去查找 时间复杂度:O(N)代码class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<in原创 2016-11-16 20:55:01 · 229 阅读 · 0 评论 -
Leetcode 264 - Ugly Number II(dp)
题意求第i个un, 定义un:质因数只包含2,3,5的数。思路算法1:状态表示:d[i]d[i],第i个UN转移方程:d[i]=min0≤j1,j2,j3<i{2d[j1],3d[j2],5d[j3]}d[i] = min_{0 \leq j_1,j_2,j_3 < i}\{2d[j_1], 3d[j_2], 5d[j_3] \}且d[i]>d[i−1]d[i] > d[i - 1]时间复杂度:O(原创 2017-02-04 15:14:52 · 216 阅读 · 0 评论 -
Leetcode 467 - Unique Substrings in Wraparound String(暴力)
题意我们有一个串s,是由abcdefg…z循环连接而成的, 给出一个字符串p,求p得所有子串在s中出现的次数。思路最初的想法是用d[i,j]d[i, j]来表示:p中的第i位,是一个j连续的串的出现次数和,但是这样会算重,比如我们的”cac”,里面c会被重复统计两次。那么,我们就需要考虑如何避免算重。假如我们的p中同时包含“abcd”和”bcd”,考虑”abcd”的子串:a, b, c, d, ab原创 2017-02-04 16:16:20 · 247 阅读 · 0 评论 -
Leetcode 403 - Frog Jump(dp or bfs)
题意给定一个石头的序列,青蛙从0开始跳,第一次只能跳一步,不能落入水中。现在,假如我从上一个石头跳到这个石头是k步,那么,我们下一次只能跳k - 1或k或k + 1步,问:青蛙最后能否调到最后一个石头上。思路算法1爆搜,本来以为会T,但是实际上中间会有很多情况会落入水中,所以bfs能过。算法2dp,我们可以这样考虑:我们当前在位置i,是从位置j经过k步到达位置i的。那么我们下一次能够达到stones原创 2017-02-04 21:21:27 · 228 阅读 · 0 评论 -
Leetcode 115 - Distinct Subsequences(dp)
题意给定两个字符串S和T,要求删除S中的某些字母使其成为T,问方案数。思路编辑距离的变形问题。状态表示:我们记d[i,j]d[i, j],从S[0, i]转换到T[0, j]的方案数。转移方程:Si==TjS_i == T_j:即当前位置不用考虑,或者删除SiS_i再考虑,即:d[i,j]=d[i−1,j−1]+d[i−1,j]d[i, j] = d[i - 1, j - 1] + d[i - 1原创 2017-02-05 14:11:31 · 230 阅读 · 0 评论 -
Leetcode330 - Patching Array(贪心)
题目链接https://leetcode.com/problems/patching-array/题意给出一个序列a[],要求往这个序列中添加最少的数字,使这个序列能组成1到n之间的所有数思路算法如下:记录当前拼凑出的最大数字sum,初始为0。tot为我们需要添加的元素值,初始化为0。当sum<nsum < n:若数组中的元素已经全部用完,tot++,加入的元素sum+1sum + 1,并且更新su原创 2017-01-13 23:05:05 · 247 阅读 · 0 评论 -
Leetcode 139 - Word Break(线性dp)
题意给一个字符串S和一个字典wordDict,要求判断是否能用wordDict内的数组成S。思路算法1区间dp,时间复杂度O(n3)O(n^3)首先将wordDict内的字符串全部丢到unordered_set<string> has里面,方便查看有没有。状态表示:d[i,j]d[i, j],区间s[i, j]能否用has内的字符串表示。转移方程:d[i,j]=d[i,k]&&d[k+1,j]d[i原创 2017-02-06 21:49:53 · 316 阅读 · 0 评论 -
Leetcode 268 - Missing Number(等差数列 or 位运算)
题意给一个大小为n的数组,里面的元素为[0, n]中缺了一个数字,求缺的那个数字。要求:O(n)O(n)时间。O(1)O(1)空间。思路算法1如果数组包含[1, n]那么它的和为n(n+1)2\frac{n(n+1)}{2}。那么我们现在只需要对数组求和,两个相减,得到的就是缺失的那个数字了。算法2利用异或。我们知道^为:1 ^ 1 = 0, 0 ^ 1 = 1。那么,就可以得到这样两个结论:原创 2017-02-16 12:39:03 · 304 阅读 · 0 评论 -
Leetcode 221 - Maximal Square(dp)
题意给定一个由01组成的矩形,要求找出矩形内由1组成的最大正方形面积。思路状态表示:d[i,j]d[i, j],以位置为矩形右下角的最大正方形的边长。r[i,j]r[i, j],第i行,到第j个位置的1的长度。c[i,j]c[i, j],第j列,到第i个位置的1的长度。转移方程:d[i,j]=min{d[i−1,j−1]+1,r[i,j],c[i,j]}d[i, j] = min\{d[i - 1,原创 2017-02-08 15:20:56 · 207 阅读 · 0 评论 -
Leetcode 85 - Maximal Rectangle(dp)
题意给定一个由01组成的矩形,要求找出矩形内由1组成的面积最大的矩形面积。思路之前写过一道类似的题,由若干个长度为1,高度不同的矩形连在一起,求最大矩形面积。这道题其实是类似的,我们只需要预处理出在位置[i, j]上,最大的1的高度,然后一行一行的处理,就和之前那道题相同了。状态表示:h[i,j]h[i, j],位置[i, j]上1的最大高度。l[i,j]l[i, j],位置[i, j]上,以h[i原创 2017-02-08 19:51:07 · 256 阅读 · 0 评论 -
Leetcode 321 - Create Maximum Number(贪心)
题意给两个数组nums1和nums2,和一个数字k,要求从nums1里面和nums2里面分别找出一些数字,构成一个新的数字,并且新的数字最大。并且nums1里面取的数字和nums2里面取的数字要保持相对顺序不变。思路之前做过一道类似的题,只给一个数组,找出k个数,维持相对顺序,求能组成的最大的数。那么,这道题,其实就是说,在nums1里面找出x个,nums2里面找出y个,x + y == k,求能组原创 2017-02-08 22:19:49 · 243 阅读 · 0 评论 -
Leetcode 97 - Interleaving String(dp)
题意给出三个字符串s1, s2, s3。求s3是否是s1和s2的interleaving(大概是交织的意思?)。思路状态表示:d[i,j,k]d[i, j, k],s10is1_{0i}和s20js2_{0j}是否是s3ks3_k的interleaving。且k == i + j。转移方程:以下第三维的k只是为了转移方程方便看,实际可以不用表示,因为k == i + j。s1i≠s2js1_i \原创 2017-02-09 01:48:49 · 259 阅读 · 0 评论 -
Leetcode 78 - Subsets(枚举)
题意求一个set的所有子集思路算法1二进制枚举算法2回溯法。代码//algorithm 1class Solution {public: vector<vector<int>> subsets(vector<int>& nums) { int n = nums.size(); vector<vector<int>> ans; for (in原创 2017-02-17 15:16:00 · 209 阅读 · 0 评论 -
Leetcode 228 - Summary Ranges(Two pointers)
题意求数组内所有连续的范围。思路用两个指针i和j,分别指向每个范围的开始位置和结束位置就好。然后去遍历数组。string to_string(int x):将x转化为一个string返回。细节注意只有一个元素或者j指向最后一个元素的情况。因此我们在遍历数组的时候,可以用j == n作为终止条件,并且终止条件特判一下避免出错。代码class Solution {private: vector原创 2017-02-17 16:16:49 · 195 阅读 · 0 评论 -
Leetcode 118 - Pascal's Triangle(模拟)
题意给定n,生成n行的Pascal三角形。思路a[i,j]=a[i−1,j−1]+a[i−1,j]a[i, j] = a[i - 1, j - 1] + a[i - 1, j]。边界情况特判一下就好。代码class Solution {private: vector<vector<int>> pas; public: vector<vector<int>> generate(i原创 2017-02-17 16:26:06 · 294 阅读 · 0 评论 -
Leetcode 90 - Subsets II(Search)
题意生成一个数组的所以子集。思路和之前的subsets一样,但是关键问题是要去重。算法1很暴力,用一个set套一个multiset来判断当前结果是否出现过。算法2我们先将数组排序,然后开始考虑怎么去重。在含有重复元素的时候,如果当前数和前面一个数相同的时候:当前仅当前面的一个数使用时,当前数字才能使用。 于是,我们添加一个use数组来记录某位置是否访问。算法3不用use数组直接跳过相同的元素。代码/原创 2017-02-17 20:51:17 · 319 阅读 · 0 评论 -
Leetcode 381 - Insert Delete GetRandom O(1) - Duplicates allowed
题意同380 - Insert Delete GetRandom O(1),只不过支持重复元素。思路pre我们先考虑还是用unordered_map+vector来做,既然支持重复元素,那么我们可以将重复元素穿成一条链,即unordered_map的结构为unordered_map<int, vector<int>> has,其中vector存储的为对应在arr里的下标。insert(val):原创 2017-02-27 20:02:53 · 362 阅读 · 0 评论 -
Leetcode 79 - Word Search(dfs)
题意求一个字符串是否能从矩形内某一点出发,沿上下左右走得到。思路dfs。算法1用use[i][j]记录位置[i, j]是否被访问过,dfs就好。算法2我们访问一个位置的时候,把它记为’#’,访问完还原即可。代码//algorithm 1const int maxn = 205;int use[maxn][maxn];class Solution {private: int m,原创 2017-02-17 22:27:15 · 245 阅读 · 0 评论 -
Leetcode 174 - Dungeon Game(二分+dp)
题意一个2D迷宫,公主在(m, n)的位置,骑士在(0, 0)的位置,并且有一个初始生命值。现在骑士要去(m, n)的位置,只能向右或者向上走。每个格子的位置上,都有BUFF和DEBUFF,现在要保持骑士在任何时刻的生命值都要大于0,求骑士的初始状态的最小生命值。思路算法1二分+dp。这是一个比较直观的思路,我们二分一下骑士初始的生命值,然后dp去判断是否合法。状态表示:d[i,j]d[i, j],原创 2017-02-09 23:12:23 · 288 阅读 · 0 评论 -
Leetcode 523 - Continuous Subarray Sum(Math)
题意给一个由非负正数组成的数组和一个数k,要求在数组中找一段长度≥2\geq 2的序列使其和是k的整数倍。思路算法1O(n2)O(n^2)时间,O(n)O(n)空间维护数组的前缀和ss,对于当前sis_i,遍历sis_i之间是否存在一个sjs_j满足(si−sj)%k=0k≠0(s_i - s_j) \% k = 0 \quad k \neq 0注意k=0k = 0的情况。算法2如果要求和刚好为k的原创 2017-02-28 11:02:12 · 1051 阅读 · 0 评论 -
Leetcode 132 - Palindrome Partitioning II(dp)
题意给定一个字符串,现在问将字符串最多分割几刀使每一段都是回文串?思路我们首先考虑因为要判断一段是否为回文串,因此需要先预处理出所有区间是否为回文串。状态表示:f[i,j]f[i, j],区间[i, j]是否为回文串。转移方程:f[i,j]=(si==sj?f[i+1,j−1]:0)f[i, j] = (s_i == s_j ? f[i + 1, j - 1] : 0)当我们预处理完成后,需要进行切原创 2017-02-10 13:05:26 · 250 阅读 · 0 评论 -
Leetcode 516 - Longest Palindromic Subsequence(dp)
题意给定一个字符串,找最长回文子序列。思路今天好像刚加的新题?花了2min切掉了。 状态表示:d[i,j]d[i, j],区间[i, j]的最长回文子序列。转移方程:si==sjs_i == s_j: d[i,j]=d[i+1,j−1]+2d[i, j] = d[i + 1, j - 1] + 2si≠sjs_i \neq s_j: d[i,j]=max(d[i+1,j],d[i,j−1])d原创 2017-02-10 13:06:51 · 327 阅读 · 0 评论 -
Leetcode 73 - Set Matrix Zeroes(Array)
题意一个数字是用vector表示的,求这个数字加1得到的vector思路设置进位标志位adc模拟一下就好,注意最前面可能会插入一个1代码73 - Set Matrix Zeroes题意一个矩阵,如果位置[i,j][i, j]上有一个元素为0,那么就将第i行的所有元素置为0,将第j列的所有元素置为0。思路算法1O(m+n)O(m + n)空间。开一个row[]和col[]分别记录哪些行,哪些列需要置为原创 2017-02-19 15:59:58 · 358 阅读 · 0 评论 -
Leetcode167 - Two Sum II - Input array is sorted(two pointers)
题意给定一个已经升序排序的数组和一个target,要求在数字中找到两个数的下标使其和为target,保证结果唯一。思路注意已经升序排好序了, 于是我们可以利用排序的性质。还是设置两个指针i和j分别指向头尾并且向中间扫描。分为如下三种情况:a[i]+a[j]==targeta[i] + a[j] == target:直接返回i和j即可。a[i]+a[j]<targeta[i] + a[j] < t原创 2017-01-19 22:59:13 · 245 阅读 · 0 评论 -
Leetcode349 - Intersection of Two Arrays(two pointers)
题意求两个数组的交集思路用两个unordered_set将讲个数组存进去,然后遍历第二个set内的每一个元素,去查看第一个set里面有没有,在存入set的过程中已经去重。先排序,用两个指针i和j分别指向两个数组的开头,并且: s1[i]<s2[j]s1[i] < s2[j]:i++s1[i]>s2[j]s1[i] > s2[j]:j++s1[i]==s2[j]s1[i] == s2[j]:原创 2017-01-19 23:02:42 · 187 阅读 · 0 评论 -
Leetcode350 - Intersection of Two Arrays II(two pointers)
题意给定两个数组,求它们的交(不去重)思路算法1利用unordered_map的,将size较大的那一个数组存到map(has)里面,has[x] = tot,代表在第一个数组内x有多少个,然后对较小的那个数组内的每个元素进行遍历并在has内查找,每次找到hax[x]–。 时间复杂度:设较小的数组大小为m,较大的数组大小为n,好像unordered_map的插入时间为O(1)O(1),那么总的时间原创 2017-01-19 23:06:53 · 227 阅读 · 0 评论 -
Leetcode287 - Find the Duplicate Number(二分)
题意将1到n之间的一些数放到n + 1大的数组中,求出那个重复出现的元素(题目保证只有一个元素重复出现,但可能出现若干次)。并且要求: 1. 额外空间为O(1)O(1)。 2. 时间复杂度小于O(n2)O(n^2)。 3. 数组是只读的,因此不能改变思路首先,时间复杂度小于O(logn)O(logn),那么我们自然能够想到是二分。可是二分什么呢?因为所有数均在1到n之间,假设有一个数重复出现,原创 2017-01-19 23:09:14 · 205 阅读 · 0 评论 -
Leetcode75 - Sort Colors(two pointers)
题意给定一个数组,只包含0,1,2,将0,1,2按照顺序排列。要求: 1. 只能开常数空间 2. 对数组只扫描一遍思路算法1算法1是最容易想到的,我们扫描一遍数组统计一下每个数字的数目,然后再扫描一遍填进去即可。算法2我们可以这样想,只需要确定每个数字的开头位置即可。 首先,0的开头位置一定是0,那么,我们只需要确定1和2的开头位置即可。于是,我们设置两个指针ind1和ind2,分别代表1的开原创 2017-01-19 23:17:49 · 232 阅读 · 0 评论 -
Leetcode141 - Linked List Cycle(链表)
题意判断一个链表是否有环思路我们可以考虑这样两个人:一个人每次走一步,一个人每次走两步,如果有环:他们总能在一圈左右后相遇,如果无环,有一个一定会走到终点。代码/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int原创 2017-01-19 23:19:53 · 179 阅读 · 0 评论 -
Leetcode19 - Remove Nth Node From End of List(链表)
题意给定一个链表和数字n,要求删除从后往前数的第n个数。并且1 pass。思路用两个指针first和second,先让second往后跑n个,然后first和second一起往后挪动,直到second->next是NULL的时候,first->next就是我们要删除的节点。感觉是个非常巧妙的思路,思想就是:我们要删除的节点和最后一个节点的距离差是n。另外,一定要注意两个边界情况: 1. 链表为空原创 2017-01-19 23:22:38 · 159 阅读 · 0 评论 -
Leetcode234 - Palindrome Linked List(链表)
题意给定一个链表,判断它是不是回文串,要求:O(n)O(n)时间O(1)O(1)空间思路翻转一下链表的前半截,注意一下边界条件和奇偶性。代码/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : v原创 2017-01-19 23:24:45 · 336 阅读 · 0 评论 -
Leetcode86 - Partition List(链表)
题意给定一个链表和数x,要求把小于x的数挪到链表前面,大于或等于x的数挪到x后面,并且保持链表的相对顺序不变。思路新开两个链表first和second,然后遍历原来的链表,小于x的挂到first上,大于等于x的挂到second上,然后把两个链表串起来就好。代码/** * Definition for singly-linked list. * struct ListNode { * i原创 2017-01-19 23:26:17 · 243 阅读 · 0 评论 -
Leetcode88 - Merge Sorted Array(two pointers)
题意就归并排序的归并:给定两个数组1和2,将2归并到1。思路如果新开空间的话还是很好做的,但是既然说了1的大小可以容纳下2,我们就考虑把2归并到1里面。开始是想法是两个数组都从第一个元素开始归并,但是存在这样一个问题:会覆盖掉1里面的元素= =。其实从两个数组的最后一个元素开始归并,因为1的后面是空出来的,因此,我们从m + n - 1的位置开始放元素,可以保证元素不会被覆盖掉。代码class So原创 2017-01-19 23:28:04 · 213 阅读 · 0 评论 -
Leetcode142 - Linked List Cycle II(链表)
题意给定一个链表,判断这个链表内是否存在环,并且求这个环的起点。思路如图所示: 我们再假设圆的周长为r,我们需要求的是a。 于是,我们设置两个指针slow和fast,slow每次走一步,fast每次走两步,并且两个都走了t时间,于是:slow:t=a+bslow: t = a + b ==>为什么不是t==a+b+mrt == a + b + mr:因为slow一旦进入环,不会跑超过一圈就会和原创 2017-01-19 23:31:28 · 212 阅读 · 0 评论 -
Leetcode 10 - Regular Expression Matching(dp)
题意正则表达式匹配,可用的元字符为.和*。问p所代表的的正则表达式能否匹配s。思路分情况讨论清楚转移就好了。状态表示:d[i,j]d[i, j],s匹配到i,p匹配到j,是否能匹配成功。转移方程:pjp_j为alpha: si=pj:d[i,j]=d[i−1,j−1]s_i = p_j: d[i, j] = d[i - 1, j - 1]si≠pj:d[i,j]=0s_i \neq p_j:原创 2017-02-10 14:56:37 · 261 阅读 · 0 评论 -
Leetcode 54 - Spiral Matrix(螺旋打印矩阵)
题意将一个矩阵螺旋打印出来。思路算法1一个需要记录很多变量的思路。首先,我们要确定走的方向是up还是down还是right还是left。然后,确定走的方向后,我们再确定每次要走多少步,分别用rs和cs来表示。当我们在最外围的时候,rs和cs都不变,但是当我们第三次转向及以后的过程中,rs和cs每次都要-1了。虽然变量很多但是想清楚了再写一遍能A。算法2直接模拟螺旋形的过程:我们分别用u, r, d,原创 2017-02-19 17:42:23 · 211 阅读 · 0 评论 -
Leetcode 472 - Concatenated Words(dp)
题意给定一个字符串的列表,列表中的一些字符串能够由列表中的另外一些字符串拼接而成(至少两个)。问能够被拼接的字符串有哪些。思路其实和wordBreak那道题一样,只不过我们需要遍历一下待拼接的那个字符串。然后剩下的就是wordBreak一样了。细节注意我们用unordered_set来判断字符串是否存在的时候要注意去掉自身。代码const int maxn = 10005;int d[maxn];原创 2017-02-10 20:37:50 · 455 阅读 · 0 评论 -
Leetcode 9 - Palindrome Number(回文数)
题意判断一个数是否是回文数,要求O(1)O(1)空间。思路如果O(1)O(1)空间的话,那么可以考虑逆转这个数字,但是会导致溢出。比如要判断123494321是否是回文串,我们只需要比较前一半和后一半,即1234和4321,所以只需要逆转数字的后一半即可。代码class Solution {public: bool isPalindrome(int x) { if (x <原创 2017-02-28 21:48:12 · 284 阅读 · 0 评论 -
Leetcode 168 - Excel Sheet Column Title(进制转化)
### 题意求一个数组在EXCEL表格下的表示,即用A-Z表示。思路即26进制下的表示。那么,就和转化进制一样。注意:A对应的数字为1,即n应该每次在-1的情况下进行转化。代码class Solution {public: string convertToTitle(int n) { string s = ""; while (n) {原创 2017-02-28 22:24:35 · 250 阅读 · 0 评论 -
Leetcode 172 - Factorial Trailing Zeroes
题意求n!n!中末尾的0的个数。思路0的出现必然是2 * 5导致的,那么只需要统计一下这些数中包含2和5的个数。因为2的个数必然远大于5,因此只需要统计5的个数。注意一些数对5的个数贡献不同,比如25=5⋅525 = 5 \cdot 5,有2个5。我们设对5的个数贡献为i个的数的个数为xix_i,x1=n/5x_1 = n / 5,并且,每出现5个贡献为1的数,就会出现一个贡献为2的数,即xi−1=原创 2017-02-28 23:27:35 · 216 阅读 · 0 评论