首页 > 其他分享 >20天 hot 100 速通计划-day19

20天 hot 100 速通计划-day19

时间:2023-08-29 19:45:30浏览次数:48  
标签:20 速通 示例 int hot grid 字符串 word1 dp

多维动态规划

62. 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1:

img

输入:m = 3, n = 7
输出:28

示例 2:

输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右
3. 向下 -> 向右 -> 向下

示例 3:

输入:m = 7, n = 3
输出:28

示例 4:

输入:m = 3, n = 3
输出:6

提示:

  • 1 <= m, n <= 100
  • 题目数据保证答案小于等于 2 * 109

强用动规结构

class Solution {
public:
    int uniquePaths(int m, int n) {
        // 定义:dp数组表示到 (0,0) 到 (i,j) 的不同路径数
        vector<vector<int>> dp(m, vector<int>(n, 0));
        
        // 定初值:将第一行和第一列的路径数初始化为1,因为只有一条路径可以到达
        for(int i = 0; i < m; i++) {
            dp[i][0] = 1;
        }
        for(int j = 0; j < n; j++) {
            dp[0][j] = 1;
        }
        
        // 定序:从左上角开始逐步计算每个位置的路径数
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                // 定式:到达当前位置的路径数等于上方位置的路径数加上左方位置的路径数
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        
        return dp[m-1][n-1];
    }
};

64. 最小路径和

给定一个包含非负整数的 *m* x *n* 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例 1:

img

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

示例 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 200
class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        // 定义:dp[i][j]表示到达格子(i, j)的最小路径和
        // 定式:dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
        // 定初值:dp[0][0] = grid[0][0]
        // 定序:从左到右,从上到下遍历

        int m = grid.size();
        int n = grid[0].size();

        // 初始化dp数组
        vector<vector<int>> dp(m, vector<int>(n, 0));
        dp[0][0] = grid[0][0];

        // 遍历计算每个格子的最小路径和
        for (int i = 1; i < m; i++) {
            dp[i][0] = dp[i-1][0] + grid[i][0];
        }
        for (int j = 1; j < n; j++) {
            dp[0][j] = dp[0][j-1] + grid[0][j];
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
            }
        }

        return dp[m-1][n-1];
    }
};

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成
class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        
        // 定义:dp[i][j]表示从字符串s的第i个字符到第j个字符是否为回文串
        vector<vector<bool>> dp(n, vector<bool>(n, false));
        
        // 定义:start记录最长回文子串的起始位置,maxLen记录最长回文子串的长度
        int start = 0, maxLen = 1;
        
        // 定初值:单个字符肯定是回文串,所以将dp[i][i]设置为true
        for (int i = 0; i < n; i++) {
            dp[i][i] = true;
        }
        
        // 定义:对dp状态数组进行遍历,外层循环从后往前,内层循环从前往后
        for (int i = n - 2; i >= 0; i--) {
            for (int j = i + 1; j < n; j++) {
                // 定式:如果s[i]等于s[j]且dp[i+1][j-1]为true(即s[i+1]到s[j-1]是回文串),则dp[i][j]为true
                if (s[i] == s[j] && (j - i == 1 || dp[i+1][j-1])) {
                    dp[i][j] = true;
                    // 如果当前回文串的长度大于maxLen,则更新最长回文子串的起始位置和长度
                    if (j - i + 1 > maxLen) {
                        maxLen = j - i + 1;
                        start = i;
                    }
                }
            }
        }
        
        // 返回最长回文子串
        return s.substr(start, maxLen);
    }
}

1143. 最长公共子序列

给定两个字符串 text1text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

  • 例如,"ace""abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例 1:

输入:text1 = "abcde", text2 = "ace" 
输出:3  
解释:最长公共子序列是 "ace" ,它的长度为 3 。

示例 2:

输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是 "abc" ,它的长度为 3 。

示例 3:

输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0 。

提示:

  • 1 <= text1.length, text2.length <= 1000
  • text1text2 仅由小写英文字符组成。
class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        // 定义:dp[i][j]表示text1的前i个字符与text2的前j个字符的最长公共子序列的长度
      	//			dp[i][j]: i-1 j-1 为结尾最长公共子序列长度
        vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));
        
        // 定初值:当i=0或j=0时,dp[i][j]=0,表示一个字符串为空时,最长公共子序列长度为0
        for(int i = 0; i <= text1.size(); i++){
            dp[i][0] = 0;
        }
        for(int j = 0; j <= text2.size(); j++){
            dp[0][j] = 0;
        }
        
        // 定式:dp[i][j] = dp[i-1][j-1] + 1,如果text1[i-1] == text2[j-1]
        //      dp[i][j] = max(dp[i-1][j], dp[i][j-1]),如果text1[i-1] != text2[j-1]
        for(int i = 1; i <= text1.size(); i++){
            for(int j = 1; j <= text2.size(); j++){
                if(text1[i - 1]==text2[j - 1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }
              	//不要求连续,需要回头
                else{
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        
        return dp[text1.size()][text2.size()];
    }
};

72. 编辑距离

给你两个单词 word1word2请返回将 word1 转换成 word2 所使用的最少操作数

你可以对一个单词进行如下三种操作:

  • 插入一个字符
  • 删除一个字符
  • 替换一个字符

示例 1:

输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

示例 2:

输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

提示:

  • 0 <= word1.length, word2.length <= 500
  • word1word2 由小写英文字母组成
class Solution {
public:
    //正统编辑距离
    //受限操作为两个字符串可以删除、插入或替换
  	// 定义:dp[i][j] 表示将 word1 的前 i 个字符转换成 word2 的前 j 个字符所需的最少操作数
    // 定式:dp[i][j]=min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])+1,当 word1[i-1] != word2[j-1] 时
    //      dp[i][j] = dp[i-1][j-1],当 word1[i-1] == word2[j-1] 时
    // 定初值:dp[0][j] = j,将空串转换成 word2 的前 j 个字符所需的最少操作数
    //        dp[i][0] = i,将 word1 的前 i 个字符转换成空串所需的最少操作数
    // 定序:从小到大依次遍历 i 和 j,计算 dp[i][j]
    int minDistance(string word1, string word2) {
        // i-1 j-1 最少操作数
        vector<vector<int>> dp(word1.size()+1, vector<int>(word2.size()+1));
        //dp[0][j]:删成空串
        //dp[i][0]:删成空串
        for(int j = 0; j<= word2.size(); j++){
            dp[0][j] =  j;
        }
        for(int i = 0; i <= word1.size(); i++){
            dp[i][0] = i;
        }
        for(int i = 1; i <= word1.size(); i++){
            for(int j = 1; j<= word2.size(); j++){
                // 相等不用操作
                if(word1[i-1] == word2[j-1]){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    dp[i][j] = min({
                        dp[i][j-1], // 删 word2 等价于 增 word1
                        dp[i-1][j], // 删 word1
                        dp[i-1][j-1], //替换
                    })+1;
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
}

标签:20,速通,示例,int,hot,grid,字符串,word1,dp
From: https://www.cnblogs.com/ba11ooner/p/17665694.html

相关文章

  • Jeecg-Boot存在前台SQL注入漏洞CVE-2023-1454
    Jeecg-boot简介jeecgBoot是一款基于BPM的低代码平台!前后端分离架构SpringBoot2.x,SpringCloud,AntDesign&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发!JeecgBoot引领新低代码开发模式OnlineCoding->代码生成器->手工MERGE,帮助J......
  • login;jsessionid=node07a53tu5ba3vd9k0wmsboxmq20.node0
    问题描述:shiro重定向到登入页面,登入地址出现了jsessionid=node07a53tu5ba3vd9k0wmsboxmq20.node0 解决方案:sessionManger中sessionIdUrlRewritingEnabled设置为false即可;<beanid="sessionManager"class="org.apache.shiro.web.session.mgt.DefaultWebSessionManage......
  • CCF HPC China2023|澎峰科技:使能先进计算,赋能行业应用
    CCFHPCChina2023圆满落幕! 桂秋八月,为期三天的中国高性能计算领域最高规格盛会——2023CCF全球高性能计算学术年会(HPCChina)在青岛红岛国际展览中心圆满落幕。行业超算大咖、顶级学界精英、先锋企业领袖参会者齐聚山东青岛,共同探讨高性能计算、人工领域、大数据等诸多前沿领域......
  • 2023.08.29T3 - summer - solution
    summerProblemSolution挺好的题,题解也写得很清楚,因此我不过是把题解抄一遍。赛时打了\(40\)分,然后挂了\(20\)分,因为不会前缀和(这个人暴力求区间和,铸币吧)。前\(40\)分就是记忆化搜索+单调栈:首先考察对于一个确定的序列,如何求出一段区间的权值和。那么首先就要知道如......
  • 20230627 java.net.URL
    介绍java.net.URLpublicfinalclassURLimplementsjava.io.SerializableURI是个纯粹的语法结构,包含用来指定Web资源的字符串的各种组成部分URL是URI的一个特例,它包含了用于定位Web资源的足够信息URL语法authority部分具有以下形式:[user-info@]host[:port]......
  • 20230627 java.net.URI
    介绍java.net.URIpublicfinalclassURIimplementsComparable,SerializableURI是个纯粹的语法结构,包含用来指定Web资源的字符串的各种组成部分URL是URI的一个特例,它包含了用于定位Web资源的足够信息URI语法URI具有以下句法:[scheme:]schemeSpecficPart[#fra......
  • 20230627 java.net.Socket
    介绍java.net.SocketpublicclassSocketimplementsjava.io.Closeable套接字(Socket)是网络软件中的一个抽象概念,负责启动该程序内部和外部之间的通信API构造器Socket()Socket(Proxyproxy)Socket(Stringhost,intport)throwsUnknownHostException,IOException......
  • 20230627 java.net.ServerSocket
    介绍java.net.ServerSocketpublicclassServerSocketimplementsjava.io.Closeable服务器套接字ServerSocket类用于建立套接字,accept用于告诉程序不停地等待,直到有客户端连接到这个端口。一旦有人通过网络发送了正确的连接请求,并以此连接到了端口上,该方法就会返回一个表......
  • 20230627 java.net.InetSocketAddress
    介绍java.net.InetSocketAddresspublicclassInetSocketAddressextendsSocketAddressAPI构造器InetSocketAddress(intport)InetSocketAddress(InetAddressaddr,intport)InetSocketAddress(Stringhostname,intport)publiccreateUnresolved创建未解析的I......
  • 20230627 java.net.InetAddress
    介绍java.net.InetAddresspublicclassInetAddressimplementsjava.io.Serializable因特网地址,是一串数字表示的主机地址(IPv4是4字节,IPv6是16字节)支持在主机名和因特网地址之间进行转换封装了一个字节序列(IPv4是4字节),byte的取值范围是[-126,125),IPv4的大小......