提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
题目列表
【第1题】最长有效括号 ⭐️⭐️⭐️
LeetCode地址:https://leetcode.cn/problems/longest-valid-parentheses/
1.题目描述
2.解题思路
我们从左到右依次遍历字符串,依次计算出cur指针所指的字符的往左的最长扩充有效区域。
如图中(1)所示,当cur指向"(“时并以该括号结尾时,其往左的最长扩充有效区域为0。
如图中(2)所示,当cur指向”)"时,我们需要知道以cur左边括号结尾的字符的有效区域长度,以计算出pre的位置。之后再判断cur和pre指向的括号是否匹配。如果不匹配,则cur位置的最长扩充有效区域为0,如图中3。否则,cur位置的最长扩充有效区域为(cur前一个位置的最长扩充有效区域长度+2)+(pre前一个位置的最长扩充有效区域长度)。
3.代码详解
class Solution {
public int longestValidParentheses(String s) {
if(s == null || s.length() < 2){
return 0;
}
//dp[i]:子串必须以i位置结尾的情况下,往左最远能扩充出多长有效区域
int[] dp = new int[s.length()];
dp[0] = 0;//以0位置结尾,没有有效括号区域
for(int i = 1; i < s.length(); i++){
if(s.charAt(i) == '('){//以该位置结尾的字符串不可能有有效区域
dp[i] = 0;
}else{ // 以 ')' 结尾
//通过dp[i-1]找出(...)左括号的位置 pre,即 '('...),其中...的长度为dp[i-1]的长度
int pre = i - dp[i-1] - 1;
if(pre >= 0){
if(s.charAt(pre) == '('){
dp[i] = dp[i-1] + 2 ;
if(pre - 1 >= 0){
dp[i] += dp[pre - 1];
}
}else{
dp[i] = 0;
}
}
}
}
int max = 0;
for(int x : dp){
max = Math.max(max,x);
}
return max;
}
}
【第2题】编辑距离 ⭐️⭐️⭐️
LeetCode地址:https://leetcode.cn/problems/edit-distance/
1.题目描述
2.解题思路
动态规划:dp[i][j]表示word1[1…i]和word2[1…j]的编辑距离大小
数组初始化如下和中间格子填充情况如下:
在计算dp[i][j]时,一共有四种情况(1)插入一个字符,向长对齐(2)删除一个字符,向短对齐(3)长度相同,最后一个字符不相同,替换一个字符(4)长度相同,最后一个字符相同,不需要操作
3.代码详解
class Solution {
public int minDistance(String word1, String word2) {
int N = word1.length();
int M = word2.length();
int[][] dp = new int[N+1][M+1]; //从word1[0,..,i]到word2[0,...,j]的编辑距离
dp[0][0] = 0;
for(int i = 1; i < N + 1;i++){
dp[i][0] = i;
}
for(int j = 1; j < M + 1; j++){
dp[0][j] = j;
}
for(int i =1; i < N + 1; i++){
for(int j = 1; j < M + 1; j++){
// aab acb 等于=> aa ac 的编辑距离
if(word1.charAt(i-1) == word2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1];
}else{
// abc aad
//否则替换一次:在 ab aa 的编辑距离基础上 + 1
dp[i][j] = dp[i-1][j-1] + 1;
}
// 从 aab aa 增加一个字符得到 aab
dp[i][j] = Math.min(dp[i][j],dp[i][j-1] +1);
// 从 aab aa 删除一个字符得到 aa
dp[i][j] = Math.min(dp[i][j],dp[i-1][j] +1);
//上面三者取最小
}
}
return dp[N][M];
}
}
【第3题】最小路径和 ⭐️
LeetCode地址:https://leetcode.cn/problems/minimum-path-sum/
1.题目描述
2.解题思路
简单的样本对应模型
3.代码详解
class Solution {
public int minPathSum(int[][] grid) {
int N = grid.length;
int M = grid[0].length;
int[][] dp = new int[N][M];
dp[0][0] = grid[0][0];
for(int i = 1; i < M;i++){
dp[0][i] = grid[0][i] + dp[0][i-1];
}
for(int i = 1; i < N;i++){
dp[i][0] = grid[i][0] + dp[i-1][0];
}
for(int i = 1; i < N; i++){
for(int j = 1; j < M; j++){
int p1 = grid[i][j] + dp[i][j-1];
int p2 = grid[i][j] + dp[i-1][j];
dp[i][j] = Math.min(p1,p2);
}
}
return dp[N-1][M-1];
}
}