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)

posted on 2020-07-10 14:22  大桃桃  阅读(427)  评论(1编辑  收藏  举报

导航