LeetCode刷题LC1-LC148(已完结)
LC148 two-sum 哈希 较难
题意:数组中找出两个加起来等于目标值的数
题解:unordered存值对应下标,注意相同数的特判
LC147 median-of-two-sorted-arrays 排序链表 较难
题意:两个有序数组中位数
题解:Kth(A,m,B,n,k),若m>n交换,pa=min(k/2,m),pb=k-pa,判断A[pa-1]和A[pb-1]的大小,若大丢掉AKth(A+pa,m-pa,B,n,k-pa),若小丢掉BKth(A,m,B+pb,n-pb,k-pb),相同取(A[pa-1]+B[pb-1])/2,注意判断m=0和k=1的情况(越界)
LC146 longest-substring-without-repeating-characters 字符串 中等
题意:最长的不具有重复字符的子串长度
题解:如果前面出现过相同字符,更新左端点l=max(pre[s[i]-'a']+1,l)
LC145 add-two-numbers 链表 较难
题意:两个链表求和
题解:模拟加法,注意某个链表长,连续进位
LC144 longest-palindromic-substring 字符串 较难
题意:最长回文子串并输出,s<=1000
题解:枚举中间点,分奇偶讨论
LC143 zigzag-conversion 字符串 中等
题意:串s,z字形排列,从上到下从左到右
题解:如果串长1直接输出,否则一行一行构造,计算跳跃距离skip=(nRows-1)*2,斜着的点j+skip-i*2
LC142 reverse-integer 复杂度 简单
题意:翻转整数x
题解:由于有溢出,所以return long long类型
LC141 string-to-integer-atoi 字符串 较难
题意:实现atoi
题解:注意需要忽略空格、引号,正负号,遇到非数字就停止,如果超过int越界输出最大或最小
LC140 palindrome-number 数学 简单
题意:整数x是否回文,不能开额外空间
题解:val=val*10+x%10,x/=10每次判断val是否等于x,注意负数不回文,x<10回文
LC139 regular-expression-matching 字符串 中等
题意:支持'.'and'*'.的通配符模式匹配
题解:dp[i][j]表示s串[0,i-1]和p串[0,j-1]是否匹配,dp[0][0]=true
for i in 0..slen,for j in 1..plen
if (j > 1 && p[j - 1] == '*') dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
else dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
LC138 container-with-most-water 数组查找 简单
题意:选两条线装水最多
题解:双指针,移动较小的一边,相同随意
LC137 integer-to-roman 字符串 简单
题意:整数转罗马
题解:一位一位转
LC136 roman-to-integer 字符串 简单
题意:罗马转整数
题解:先把字符转成值,若存在递增区间,减掉2倍,最后求和
LC135 longest-common-prefix 复杂度 中等
题意:n个串最长公共前缀
题解:s.substr(0,i)表示从0开始截取i个字符
LC134 3sum 哈希查找 较难
题意:a+b+c=0的不重复三元组
题解:排序,枚举两维a和b,剩下的c指针,注意去重a1=a2或b1=b2
LC133 3sum-closest 数组排序哈希 中等
题意:a+b+c最接近target
题解:排序,枚举两维a和b,剩下的c指针,对c来说若c[k-1]比c[k]更优,那么不管是a[i+1]还是b[j+1]都是选择c[k-1],所以就满足单调性
LC132 4sum 哈希查找 较难
题意:a+b+c+d=target的不重复四元组
题解:排序,枚举三维a和b和c,剩下的d指针,注意去重a1=a2或b1=b2或c1=c2
LC131 letter-combinations-of-a-phone-number 查找 中等
题意:数字串在手机上按的所有情况
题解:哈希数字对应串后暴力
LC130 remove-nth-node-from-end-of-list 链表 中等
题意:删除链表导数第n个节点
题解:前后指针,距离n个节点,注意删除头节点移动head,全删完head=NULL
LC129 valid-parentheses 栈 中等
题意:是否合法括号序列
题解:栈,遇到右判断栈顶是否对应,最后判断栈是否为空
LC128 generate-parentheses 查找 中等
题意:n对括号,生成合法括号序列
题解:深搜,如果已经填了a个左括号,b个右括号,如果a<b才可以填右括号
LC127 merge-k-sorted-lists 链表 较难
题意:合并k个已经排序的链表
题解:每次找k个链表中最小的节点
LC126 swap-nodes-in-pairs 链表 中等
题意:交换链表每相邻两个
题解:前后指针交换
LC125 reverse-nodes-in-k-group 链表 中等
题意:每k个元素翻转
题解:求出长度,每k个元素翻转
LC124 remove-duplicates-from-sorted-array 数组 中等
题意:删除数组重复元素
题解:指针,注意A == NULL
LC123 remove-element 数组 简单
题意:删除数组给定元素
题解:指针
LC122 implement-strstr 字符串 较难
题意:实现strstr
题解:简单的话暴力,复杂的话KMP
LC121 divide-two-integers 模拟 较难
题意:两数相除
题解:模拟除法过程,最后利用符号位判断正负
LC120 substring-with-concatenation-of-all-words 高级算法字符串 较难
题意:一个串S,求所有起点,使得words中的所有串串联
题解:暴力+剪枝
LC119 next-permutation 数组 中等
题意:返回下一个全排列
题解:next_permutation(num.begin(), num.end())
LC118 longest-valid-parentheses 栈 较难
题意:求最长合法括号序列
题解:dp[i]表示[0,i)的最长合法括号序列,
if (s[i - 1] == ')') {
if (s[i - 2 - dp[i - 1]] == '(') dp[i] = dp[i - 1] + 2;
dp[i] += dp[i - dp[i]];
} ans = max(ans, dp[i]);
LC117 search-in-rotated-sorted-array 查找 中等
题意:一个转动过的有序数组,求target是否出现
题解:二分求出最右边位置,再次二分查找是否出现target
LC116 search-for-a-range 排序查找 中等
题意:单调不减数组,查找等于target的区间
题解:两次二分,第一次最左边,第二次最右边
LC115 search-insert-position 查找 中等
题意:单调不减数组,如果target存在则返回下标,如果不存在返回插入位置
题解:二分找到<=target的最右边位置,判断是否存在
LC114 valid-sudoku 查找 中等
题意:判断给定数独局面是否合法
题解:r[9][9]代表行,c[9][9]代表列,b[9][9]代表i / 3 * 3 + j / 3块
LC113 sudoku-solver 查找 较难
题意:求数独的解保证唯一
题解:深搜
LC112 count-and-say 字符串 中等
题意:给一个n和生成序列方式,求第n个序列
题解:双指针
LC111 combination-sum 查找 较难
题意:给出一组候选数C和一个目标数T,找出候选数中加起来和等于T的所有组合。C中的数字在组合中可以被无限次使用
题解:先排序C,再深搜
LC110 combination-sum-ii 查找 中等
题意:给出一组候选数C和一个目标数T,找出候选数中加起来和等于T的所有组合。C中的每个数字在一个组合中只能使用一次
题解:比上题多一个if (i > pos + 1 && c[i] == c[i - 1]) continue;
LC109 first-missing-positive 数组 较难
题意:给出一个无序的整数型数组,求不在给定数组里的最小的正整数
题解:把num[i]换到num[num[i] - 1]的位置,由于不可以开数组,所有可以用while不断交换解决,注意num <= 0或num > n不要考虑
LC108 trapping-rain-water 栈 中等
题意:下雨之后这个地形可以存储多少水
题解:找到最大值下标,左边计算一下,右边计算一下
LC107 multiply-strings 字符串 较难
题意:大数相乘
题解:模拟,a位数*b位数最多a+b位数,最后去掉前导0
LC106 wildcard-matching 字符串 较难
题意:"?"匹配1个,"*"可匹配任意,问S和T是否匹配
题解:dp[i][j]表示S匹配到[0,i]T匹配到[0,j]
dp[0][0] = true;
for (int j = 1; j < plen + 1; j++) {
if (p[j - 1] == '*') dp[0][j] = true;
else break;
}
for (int i = 0; i < slen; i++) {
for (int j = 0; j < plen; j++) {
if (p[j] == s[i] || p[j] == '?') dp[i + 1][j + 1] = dp[i][j];
else if (p[j] == '*') dp[i + 1][j + 1] = dp[i][j] || dp[i + 1][j] || dp[i][j + 1];
}
}
LC105 jump-game-ii 贪心 中等
题意:LC95的基础上最少步数
题解:la表示上一次跳跃的最远距离,maxr表示当前跳跃能到的最远距离,当i>la说明需要多一次跳跃++ans,la=maxr
LC104 permutations 递归分治 中等
题意:num数组,输出全排列
题解:sort(num),next_permutation
LC103 permutations-ii 递归分治 中等
题意:LC104,加一个元素可能重复
题解:同LC104
LC102 rotate-image 数组 简单
题意:二维数组顺时针旋转90°,不开额外空间
题解:从外圈往内圈,得到四个位置的数,交换
int time = (n + 1) / 2;
for (int i = 0; i < time; i++) {
for (int j = 0; j < n - 2 * i - 1; j++) {
int dx1 = i, dy1 = i + j;
int dx2 = i + j, dy2 = n - 1 - i;
int dx3 = n - 1 - i, dy3 = n - 1 - i - j;
int dx4 = n - 1 - i - j, dy4 = i;
swap(matrix[dx4][dy4], matrix[dx1][dy1]);
swap(matrix[dx3][dy3], matrix[dx4][dy4]);
swap(matrix[dx2][dy2], matrix[dx3][dy3]);
}
}
LC101 anagrams 字符串 中等
题意:给出一个字符串数组,返回所有互为“换位词(anagrams)”的字符串的组合(换位词就是包含相同字母,但字母顺序可能不同的字符串)
题解:每个串从小到大排序,存入map
LC100 powx-n 分治 较难
题意:实现pow(x, n),(虽然n是double,但好像n为整数??)
题解:快速幂,如果n为负数,1/快速幂的结果
LC99 n-queens 查找 中等
题意:n皇后所有解集
题解:dfs,需要注意行列斜是否合法
LC98 n-queens-ii 查找 简单
题意:n皇后解集个数
题解:LC99输出ans.size()
LC97 maximum-subarray 贪心 简单
题意:最大子段和
题解:类似于dp的思想,由于dp[i]只跟dp[i - 1]有关,所以用sum就可以表示
int sum = 0, max = A[0];
for(int i = 0; i < n; i++) {
sum += A[i];
if(max < sum) max = sum;
if(sum < 0) sum = 0;
}
LC96 spiral-matrix 数组 较难
题意:n*m数组按螺旋顺序表示
题解:需要注意的是第三如果up=down相当于那一行放入队列两次(因为第一行已经放入了),同理第四行
void dfs(int up, int down, int left, int right, vector<vector<int> > &matrix) {
if (up > down || left > right) return;
for (int i = left; i <= right; i++) ans.push_back(matrix[up][i]);
for (int i = up + 1; i <= down; i++) ans.push_back(matrix[i][right]);
if (up != down) for (int i = right - 1; i >= left; i--) ans.push_back(matrix[down][i]);
if (left != right) for (int i = down - 1; i >= up + 1; i--) ans.push_back(matrix[i][left]);
dfs(up + 1, down - 1, left + 1, right - 1, matrix);
}
LC95 jump-game 贪心 中等
题意:给出一组非负整数A,A[i]表示在i最多能跳到i + A[i],问能否跳到A[n - 1]
题解:for (int i = 0; i < n; i++) maxr = max(maxr, i + A[i])最后return maxr >= n - 1
LC94 merge-intervals 数组 较难
题意:[start,end]把有重叠的区间合并
题解:按左段点从小到大,相同按右段点从小到大,双指针
LC93 insert-interval 数组排序 较难
题意:LC94支持插入一个区间
题解:把新区间插入原vector,然后LC94
LC92 length-of-last-word 字符串 中等
题意:只含空格大小写字符串s,求最后一个单词长
题解:去掉最后的空格,倒着遍历
LC91 spiral-matrix-ii 数组 简单
题意:1-n^2填入螺旋矩阵
题解:x = 0, y = -1模拟四个方向填数,dir = (dir + 1) % 4
LC90 permutation-sequence 高级算法 较难
题意:1-n求第k个全排列
题解:next_permutation(f, f + n)
LC89 rotate-list 链表 较难
题意:链表向右转动k个
题解:先求出长度,如果k %= len,k = len - k - 1,第k个就是新头节点
LC88 unique-paths 动态规划 简单
题意:(1,1)->(m,n)的路径数
题解:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
LC87 unique-paths-ii 动态规划 中等
题意:带障碍物的,(1,1)->(m,n)的路径数
题解:不为障碍物dp[i][j] = dp[i - 1][j] + dp[i][j - 1],否则dp[i][j] = 0
LC86 minimum-path-sum 动态规划 中等
题意:(1,1)->(m,n)最小路径和
题解:dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
LC85 merge-two-sorted-lists 链表 简单
题意:合并两个有序链表
题解:新建一个伪头节点,每次循环取出小的
LC84 add-binary 字符串 中等
题意:二进制串+二进制串
题解:二进制大数相加
LC83 valid-number 字符串 困难
题意:串是否合法数字
题解:java,Double.valueOf(s)若出现异常return false,这里需要注意最后的字母不能识别,例如“1f”
LC82 plus-one 数组 中等
题意:int数组加1
题解:直接模拟,最后翻转reverse(ans.begin(), ans.end()),注意最后的进位
LC81 text-justification 字符串 困难
题意:文本对齐
题解:找到每一行需要填几个单词,求出每两个之间的空格数,判断是否一行只有一个单词和是否最后一行
LC80 sqrtx 分治 中等
题意:求x的平方根
题解:库函数(牛顿逼近),循环,二分
LC79 climbing-stairs 动态规划 简单
题意:n步,一次爬1或2
题解:dp[i] = dp[i - 1] + dp[i - 2]
扩展:当n很大时可以用矩阵快速幂
LC78 simplify-path 字符串 较难
题意:简化路径
题解:需要考虑一个"."和两个".",最后添加上"/"
LC77 edit-distance 动态规划 中等
题意:word1->word2,可以添加删除替换
题解:为了方便添加一个"."在开头,dp[i][j]表示word1匹配到i,word2匹配到j
for (int i = 0; i < word1.size(); i++) dp[i][0] = i;
for (int i = 0; i < word2.size(); i++) dp[0][i] = i;
for (int i = 1; i < word1.size(); i++) {
for (int j = 1; j < word2.size(); j++) {
if (word1[i] == word2[j]) dp[i][j] = min(dp[i][j], dp[i - 1][j - 1]);
else {
int temp = min(dp[i - 1][j], dp[i][j - 1]);
//替换
dp[i][j] = min(temp, dp[i - 1][j - 1]) + 1;
}
}
}
return dp[word1.size() - 1][word2.size() - 1];
LC76 set-matrix-zeroes 查找 简单
题意:如果matrx[i][j]=0,置第i行j列为0
题解:如果第一行有0,置r=true,如果第一列有0,置c=true,然后利用第一行第一列判断该行该列是否需要填0,最后恢复第一行第一列
LC75 search-a-2d-matrix 数组查找 中等
题意:二维数组,每一行单调不减,下一行第一个大于上一行最后一个
题解:两次二分,第一次二分第一维,找到<=target最接近的下标,第二次二分找到值
LC74 sort-colors 数组 简单
题意:只含0,1,2的数组排序(不使用库函数)
题解:a[3]统计个数
LC73 minimum-window-substring 贪心 中等
题意:在S中找出最短的包含T中所有字符的子串
题解:t[i]表示T串中字符出现的个数,vis[i]表示字符是否出现过,ok表示当前区间还有多少个字符没满足,可以维护一个指针r,每次把指针往右移
LC72 combinations 查找 中等
题意:1-n取k个数的全部组合
题解:dfs
LC71 subsets 动态规划 中等
题意:求S的所有子集
题解:由于输出是按个数排序,所以需要用bfs
LC70 word-search 查找 中等
题意:二维数组求给定串是否出现
题解:dfs,要判断合法的个数是否等于串长
LC69 remove-duplicates-from-sorted-array-ii 数组 中等
题意:单调不减数组重复元素最多不超过2个
题解:双指针
LC68 search-in-rotated-sorted-array-ii 排序查找 中等
题意:LC117 search-in-rotated-sorted-array基础上加了个重复元素
题解:二分,如果A[l]<A[mid]说明在左半,如果target在[A[l],A[mid]]之间更新r,否则更新l,如果A[mid]<A[r]说明在右半,同理左半,否则说明A[l]=A[r]=A[mid]左半右半都有可能,只能l++,最坏复杂度O(n),期望复杂度O(logn)
LC67 remove-duplicates-from-sorted-list 链表 简单
题意:移除递增链表重复节点,保留一个
题解:前后指针,如果p->val=q->val,p不变、q往下走,否则p、q都往下走
LC66 remove-duplicates-from-sorted-list-ii 链表 中等
题意:移除递增链表重复节点,全删
题解:新增伪头节点h是为了方便判断第一个数,h->next=head,cur=h,pc=cur->next,pcc=pc->next,如果pc->val=pcc->val则没有重复移动cur=cur->next,否则有重复,不断移动pcc=pcc->next,直到找到不重复节点,令cur->next=pcc
LC65 largest-rectangle-in-histogram 栈 中等
题意:一维数组求最大矩形面积
题解:维护一个单增的单调栈,如果当前height[i]<height[q[tail]]那么需要把q[tail]节点弹出(这里弹出需要考虑q[tail - 1]到q[tail]之间,因为q[tail]可能已经把前面比它大的弹出了),计算面积是从[q[tail - 1], i) * height[q[tail]],如果没有q[tail - 1]那么是[0,i)* height[q[tail]]
LC64 maximal-rectangle 贪心 较难
题意:二维数组求最大全1矩形面积
题解:维护一个h[j] = matrix[i][j] == '1' ? d[j] + 1 : 0,对于一行来说就变成了LC65 largest-rectangle-in-histogram的单调栈做法
LC63 partition-list 链表 中等
题意:链表小于x的放在左边
题解:开一个数组存放小的和大的
LC62 scramble-string 字符串动态规划 中等
题意:s2是否是s1的乱序字符串
题解:记忆化搜索,dfs(s1左,s2左) && dfs(s1右,s2右) || dfs(s1左,s2右) && dfs(s1右,s2左)
LC61 merge-sorted-array 数组 中等
题意:给出两个有序的整数数组A和B,请将数组B合并到数组A中,变成一个有序的数组
题解:每次取出A和B中较大那个,放入A的末尾
LC60 gray-code 动态规划 中等
题意:生成一个格雷串
题解:for (int i = 0; i < 1 << n; i++) ans.push_back(i ^ (i >> 1))
LC59 decode-ways 动态规划 较难
题意:给一个数字串,A->1,Z->26,求不同解码串数量
题解:dp[i]表示[0, i]解码串数量,如果s[i] != 0那么dp[i] += dp[i - 1],如果s[i - 1]和s[i]组合[10,26]之间dp[i] += dp[i - 2],注意如果s[i] == 0并且不能和前面合并return 0
LC58 subsets-ii 动态规划 较难
题意:LC71 subsets带有重复数字
题解:LC71是bfs版本,这题是dfs版本,重复数字就是判断if (i > pos + 1 && S[i] == S[i - 1]) continue;
LC57 reverse-linked-list-ii 链表 较难
题意:链表m位置到n位置之间的区间反转
题解:每次都把后面的节点插入到反转部分的最前面去
LC56 restore-ip-addresses 递归分治 较难
题意:给一个数字串,输出所有合法IP串
题解:dfs,如果为第一个数字不加".",否则加".",注意前导0
LC55 binary-tree-inorder-traversal 树 简单
题意:非递归中序遍历
题解:栈,如果当前节点u有right,把right入栈置u->right=NULL,再把u入栈,如果有left,再把left入栈置u->left=NULL,如果u->left==NULL输出u
LC54 unique-binary-search-trees 树 简单
题意:1-n的二叉搜索树个数
题解:卡特兰数C(2n, n) / (n + 1)
LC53 unique-binary-search-trees-ii 树 中等
题意:输出上题的所有树
题解:分治vector<TreeNode*> left = dfs(l, i - 1),vector<TreeNode*> right = dfs(i + 1, r),遍历left和right,root->left = left[j],root->right = right[k]
LC52 interleaving-string 字符串动态规划 较难
题意:s3是否可由s1和s2交织而成
题解:dp[i][j]表示s1匹配到i,s2匹配到j,s3匹配到i + j
dp[0][0] = 1;
for (int i = 0; i < len1; i++) {
if (s1[i] == s3[i]) dp[i + 1][0] = 1;
else break;
}
for (int i = 0; i < len2; i++) {
if (s2[i] == s3[i]) dp[0][i + 1] = 1;
else break;
}
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (s1[i - 1] == s3[i + j - 1]) dp[i][j] |= dp[i - 1][j];
if (s2[j - 1] == s3[i + j - 1]) dp[i][j] |= dp[i][j - 1];
}
}
return dp[len1][len2];
LC51 validate-binary-search-tree 树 中等
题意:是否二叉搜索树
题解:如下代码,同理右
if (root->left != NULL) {
if (root->left->val >= root->val) return false;
else ans &= isValidBST(root->left);
}
LC50 recover-binary-search-tree 树 中等
题意:二叉搜索树其中两个节点被错误的交换了
题解:中序遍历可知,只需要交换两个下降区间的头和尾
LC49 same-tree 树 入门
题意:两棵树是否相同
题解:递归,如果p为空并且q为空返回true,如果p为空或者q为空返回false,如果值不等返回false
LC48 symmetric-tree 树 中等
题意:一颗二叉树是否对称
题解:一颗往左dfs一颗往右dfs,dfs(p->left, q->right) && dfs(p->right, q->left),判断同上题
LC47 binary-tree-level-order-traversal 树 简单
题意:层序遍历
题解:bfs
LC46 binary-tree-zigzag-level-order-traversal 树 较难
题意:层序遍历,第一层左到右第二层右到左
题解:bfs,偶数层reverse
LC45 maximum-depth-of-binary-tree 树 入门
题意:二叉树的最大深度
题解:deep = max(deep, 1 + maxDepth(root->left))
LC44 construct-binary-tree-from-preorder-and-inorder-traversal 树 中等
题意:先序中序建树
题解:分治,root = preorder[l1],找到中序的节点位置p,计算个数cnt = p - l2
root->left = dfs(l1 + 1, l1 + cnt, l2, p - 1, preorder, inorder);
root->right = dfs(l1 + cnt + 1, r1, p + 1, r2, preorder, inorder);
LC43 construct-binary-tree-from-inorder-and-postorder-traversal 递归树 中等
题意:中序后序建树
题解:分治,root = postorder[r1],其余同LC44
root->left = dfs(l1, l1 + cnt - 1, l2, p - 1, postorder, inorder);
root->right = dfs(l1 + cnt, r1 - 1, p + 1, r2, postorder, inorder);
LC42 binary-tree-level-order-traversal-ii 树 中等
题意:从底到顶的层序遍历
题解:得到从顶到底,reverse
LC41 convert-sorted-array-to-binary-search-tree 数组树 较难
题意:升序数组转成二叉搜索树
题解:分治,dfs(l, r),mid = (l + r + 1) / 2,mid作为根节点,左节点=dfs(l, mid - 1),右节点dfs(mid + 1, r)
LC40 convert-sorted-list-to-binary-search-tree 树链表 较难
题意:升序单链表转成二叉搜索树
题解:分治,LC41的思路,由于单链表mid不好找,所以采用快慢指针,快指针每次走两步,慢指针每次走一步
LC39 balanced-binary-tree 树 简单
题意:判断二叉树是否平衡
题解:l = 1 + dfs(root->left),r = 1 + dfs(root->right)
LC38 path-sum 树查找 中等
题意:是否有根到叶子节点路径和为sum
题解:dfs,如果一个节点没有左右则为叶子节点
LC37 path-sum-ii 树查找 中等
题意:求出LC38的所有合法解
题解:dfs,LC38的基础上加一个记录路径
LC36 distinct-subsequences 字符串动态规划 中等
题意:给定两个字符串S和T,返回S子序列等于T的不同子序列个数有多少个
题解:为了方便计算在S和T之前加入一个".",dp[i][j]表示S串匹配了[1,i],T串匹配了[1, j],初始化dp[i][0] = 1
if (s[i] == t[j]) dp[i][j] = dp[i - 1][j - 1]; // 不删掉i
dp[i][j] += dp[i - 1][j]; // 删i
LC35 populating-next-right-pointers-in-each-node 树 简单
题意:完全二叉树,把层序遍历用next指向
题解:如果当前节点root有left和right,那么root->left->next = root->right,如果当前节点root有right和next,那么root->right->next = root->next->left
LC34 populating-next-right-pointers-in-each-node-ii 树 中等
题意:LC35改成任意二叉树
题解:模拟层序遍历,合法节点为当前节点root有左或者有右,dummy表示第一个合法节点
LC33 pascals-triangle 模拟 中等
题意:生成杨辉三角前n行
题解:模拟
LC32 pascals-triangle-ii 模拟 中等
题意:第k行杨辉三角
题解:C(k, i)(0 <= i <= k)
LC31 triangle 动态规划 中等
题意:三角形顶到底最小路径和
题解:dp[i][j]表示从n - 1行到第i行的第j列最小数字和,由于i只和i - 1有关,所以可以滚动i
LC30 best-time-to-buy-and-sell-stock 数组 简单
题意:股票买卖一次交易
题解:l = min(l, prices[i]),ans = max(ans, prices[i] - l)
LC29 best-time-to-buy-and-sell-stock-ii 数组 简单
题意:股票买卖无限交易
题解:if (prices[i] > prices[i - 1]) sum += prices[i] - prices[i - 1]
LC28 best-time-to-buy-and-sell-stock-iii 数组 较难
题意:股票买卖最多两次交易
题解:buy1表示第一次买,sell1表示第一次卖,buy2和sell2同理
for (int i = 0; i < prices.size(); i++) {
buy1 = min(buy1, prices[i]);
sell1 = max(sell1, prices[i] - buy1);
buy2 = max(buy2, sell1 - prices[i]);
sell2 = max(sell2, buy2 + prices[i]);
}
LC27 binary-tree-maximum-path-sum 树 较难
题意:二叉树路径和最大
题解:dfs
int dfs(TreeNode *root) {
if (root == nullptr) return 0;
int l = max(0, dfs(root->left));
int r = max(0, dfs(root->right));
ans = max(ans, root->val + l + r);
return max(l, r) + root->val;
}
LC26 valid-palindrome 递归 较难
题意:串是否回文,忽略仅考虑字母和数字
题解:先把字母和数字处理出来,直接判断回文,注意转成小写或大写
LC25 word-ladder 查找 较难
题意:出所有的从初始单词到目标单词的最短转换序列的长度
题解:bfs,bfs处理出最短路径
LC24 word-ladder-ii 查找 困难
题意:LC25输出所有解集
题解:bfs+dfs,bfs处理出最短路径,dfs根据最短路径求出解集
LC23 longest-consecutive-sequence 数组查找 中等
题意:最长的连续元素序列的长度
题解:排序后双指针,注意处理相同的
LC22 sum-root-to-leaf-numbers 树 中等
题意:根节点到叶子节点的所有路径表示的数字之和
题解:由于输出的是int,所以不需要大数(面向输出做题)直接dfs
LC21 surrounded-regions 数组 较难
题意:二维数组被X包围的O改成X
题解:如果O在边缘那么bfs得到的全是不用删的,最后把剩下的O删了
LC20 palindrome-partitioning 字符串 较难
题意:给定一个字符串s,分割s使得s的每一个子串都是回文串,返回所有的回文分割结果
题解:dfs,每次循环把s切割掉前面i个
LC19 palindrome-partitioning-ii 动态规划 较难
题意:LC20求最少切割
题解:为了计算方便在s之前加一个".",dp[i]表示切第i个位置,如果[j, i]回文,dp[i] = min(dp[i], dp[j - 1] + 1),最后输出dp[n] - 1
LC18 clone-graph 图 中等
题意:深拷贝图
题解:dfs,unordered_map<int, UndirectedGraphNode*> used,因为题目里有说明值不同,值对应一个节点
LC17 gas-station 贪心 中等
题意:车站i加油gas[i]费油cost[i],问从哪个站开始可以走所有车站
题解:从start出发,如果油量足够,可以一直向后走 end++;油量不够的时候,start向后退最终start == end的时候,如果有解一定是当前start所在位置
LC16 candy 动态规划 较难
题意:n个小朋友,每个小朋友至少一颗糖,第i个小朋友得分比旁边高的小朋友糖果多,问总共最少需要多少糖果
题解:正反dp,正着dp求出i和i-1,反着dp求出i和i+1
LC15 single-number 复杂度 入门
题意:一个数出现一次其余都出现两次
题解:两个数相同异或不影响,求出所有数异或
LC14 single-number-ii 复杂度 中等
题意:一个数出现一次其余都出现三次
题解:真值表做法太神了学不来。出现3次说明第i位为3N或3N+1,只要把3N+1的位求出来求和
LC13 copy-list-with-random-pointer 链表 中等
题意:深拷贝链表带随机指针
题解:先交替复制,再处理随机指针,再分裂出新的
LC12 word-break 动态规划 较难
题意:单词能否被分成dict中的单词
题解:LC19的dp思路
LC11 word-break-ii 动态规划 困难
题意:LC12解集
题解:dfs
if(dict.find(s) != dict.end()) res.push_back(s);//剩下的单词就是dict中的
//需要分裂
vector<string> temp = wordBreak(s.substr(0,i),dict);
for (int i = 0; i < temp.size(); i++) temp[i] += " " + word;
res.insert(res.begin(), temp.begin(), temp.end());
LC10 linked-list-cycle 链表 简单
题意:链表是否有环
题解:快慢指针,快指针一次走两步,判断是否相遇,如果其中一个指针为空则无环
LC9 linked-list-cycle-ii 链表 中等
题意:链表是否有环,返回环开始的节点
题解:思路同LC10,相遇后把慢指针置为head,快慢指针同时一步一步走直到相遇
LC8 reorder-list 链表 较难
题意:链表变成L0LnL1Ln-1
题解:开个vector数组存放链表,双指针处理
LC7 binary-tree-preorder-traversal 树 简单
题意:给一棵树,求先序遍历(不能用dfs)
题解:栈模拟,先right再left
LC6 binary-tree-postorder-traversal 树中等
题意:给一棵树,求后序遍历(不能用dfs)
题解:vector,每次取出tail节点,如果right,left不为空则输出,否则push进vec
LC5 insertion-sort-list 排序 较难
题意:链表插入排序
题解:每次找个最小的节点交换
LC4 sort-list 排序链表 较难
题意:链表归并排序
题解:找中点采用快慢指针,分治区间内把小放前大放后
LC3 max-points-on-a-line 穷举 困难
题意:n个点求直线上的最多点数量
题解:三重循环暴力,注意相同点
LC2 evaluate-reverse-polish-notation 栈 较难
题意:逆波兰表达式
题解:栈模拟,stoi(tokens[i])可以转成int,注意负数和减号取分
LC1 Minimum Depth of Binary Tree 树 较难
题意:二叉树根到叶子节点最短路径
题解:dfs(root, dep),如果为叶子节点ans = min(ans, dep)