当前位置: 首页 > article >正文

力扣11.4

97. 交错字符串

给定三个字符串 s1s2s3,请你帮忙验证 s3 是否是由 s1s2 交错 组成的。

两个字符串 st 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空
子字符串

  • s = s1 + s2 + ... + sn
  • t = t1 + t2 + ... + tm
  • |n - m| <= 1
  • 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...

注意:a + b 意味着字符串 ab 连接。

数据范围

  • 0 <= s1.length, s2.length <= 100
  • 0 <= s3.length <= 200
  • s1s2、和 s3 都由小写英文字母组成

分析

记忆化搜索, d p ( i , j , k ) dp(i,j,k) dp(i,j,k)表示 s 3 s3 s3的前 k k k个字符能否由 s 1 s1 s1的前 i i i个和 s 2 s2 s2的前 j j j个交错构成,若

  • s 3 [ k ] = = s 1 [ i ] s3[k]==s1[i] s3[k]==s1[i],则 d f s ( i + 1 , j , k + 1 ) dfs(i+1,j,k+1) dfs(i+1,j,k+1)
  • s 3 [ k ] = = s 2 [ j ] s3[k]==s2[j] s3[k]==s2[j],则 d f s ( i , j + 1 , k + 1 ) dfs(i,j+1,k+1) dfs(i,j+1,k+1)

代码

class Solution {
public:
    const static int N = 105;
    int dp[N][N][2 * N];
    int dfs(int i1, int i2, int i3, string s1, string s2, string s3) {
        if(i3 == s3.size() && i1 == s1.size() && i2 == s2.size()) return true;
        if(i1 > s1.size() || i2 > s2.size()) return false;
        int &res = dp[i1][i2][i3];
        if(res != -1) return res;
        res = 0;
        if(s3[i3] == s1[i1]) {
            if(dfs(i1 + 1, i2, i3 + 1, s1, s2, s3)) res = 1;
        } 
        if(s3[i3] == s2[i2]) {
            if(dfs(i1, i2 + 1, i3 + 1, s1, s2, s3)) res = 1;
        }
        return res;
    }
    bool isInterleave(string s1, string s2, string s3) {
        int n1 = s1.size(), n2 = s2.size(), n3 = s3.size();
        memset(dp, -1, sizeof(dp));
        if(n3 != n1 + n2) return false;
        // dp[0][0][0] = true;
        bool res = dfs(0, 0, 0, s1, s2, s3);
        return res;
    }
};

583. 两个字符串的删除操作

给定两个单词 word1word2 ,返回使得 word1word2 相同所需的最小步数。

每步 可以删除任意一个字符串中的一个字符。

数据范围

  • 1 <= word1.length, word2.length <= 500
  • word1word2 只包含小写英文字母

分析

求出两个单词的最长公共子序列长度为 k k k,最后结果为 w o r d 1. s i z e ( ) + w o r d 2. s i z e ( ) − 2 ∗ k word1.size()+word2.size()-2*k word1.size()+word2.size()2k

代码

class Solution {
public:
    const static int N = 505;
    int dp[N][N];
    int minDistance(string word1, string word2) {
        int n = word1.size(), m = word2.size();
        for(int i = 0; i < n; i ++ ) {
            for(int j = 0; j < m; j ++ ) {
                dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1]);
                if(word1[i] == word2[j]) dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + 1);
            }
        }
        return n + m - 2 * dp[n][m];
    }
};

2218. 从栈中取出 K 个硬币的最大面值和

一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币。

每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。

给你一个列表 piles ,其中 piles[i] 是一个整数数组,分别表示第 i 个栈里 从顶到底 的硬币面值。同时给你一个正整数 k ,请你返回在 恰好 进行 k 次操作的前提下,你钱包里硬币面值之和 最大为多少 。

数据范围

  • n == piles.length
  • 1 <= n <= 1000
  • 1 <= piles[i][j] <= 105
  • 1 <= k <= sum(piles[i].length) <= 2000

分析

这题可以转化为分组背包,预处理每个栈的前缀和,每个前缀和实际就是每个组的物品,且每组只能选一个

代码

class Solution {
public:
    const static int N = 1005;
    int dp[N][N * 2];
    vector<vector<int>> pre;
    int maxValueOfCoins(vector<vector<int>>& piles, int k) {
        int n = piles.size();
        pre.resize(n);
        for(int i = 0; i < n; i ++ ) {
            pre[i].resize(piles[i].size());
            for(int j = 0; j < piles[i].size(); j ++ ) {
                if(j == 0) pre[i][j] = piles[i][j];
                else pre[i][j] = pre[i][j - 1] + piles[i][j];
            }
        }
        memset(dp, -0x3f, sizeof(dp));
        dp[0][0] = 0;
        for(int i = 0; i < n; i ++ ) {
            for(int j = 0; j <= k; j ++ ) {
                dp[i + 1][j] = dp[i][j];
                for(int z = 0; z < pre[i].size(); z ++ ) {
                    if(j >= z + 1) {
                        dp[i + 1][j] = max(dp[i + 1][j], dp[i][j - z - 1] + pre[i][z]);
                    }
                }
            }
        }
        return dp[n][k];
    }
};

http://www.kler.cn/a/381260.html

相关文章:

  • 基于vue的商城小程序的毕业设计与实现(源码及报告)
  • kotlin sortedBy 与sortedWith的区别
  • Nacos概述与集群实战
  • 记录一次面试中被问到的问题 (HR面)
  • STM32供电参考设计
  • 对快速由表及里说拜拜/如何正确运用由表及里
  • 微信小程序 基于协同过滤算法的的校园音乐推荐系统
  • 大客户营销数字销售实战讲师培训讲师唐兴通专家人工智能大模型销售客户开发AI大数据挑战式销售顾问式销售专业销售向高层销售业绩增长创新
  • 低代码解锁跨平台应用开发新境界
  • Elasticsearch核心概念
  • [渲染层网络层错误] net::ERR_CONTENT_LENGTH_MISMATCH 问题解决
  • 【TextIn:开源免费的AI智能文字识别产品(通用文档智能解析识别、OCR识别、文档格式转换、篡改检测、证件识别等)】
  • 利用爬虫爬取网站信息
  • spring-data-aop Repository层的增删查改
  • 基于C#的Windows编程:后台窗口和坐标转换
  • 网络原理(应用层)->HTTPS解
  • odrive代码阅读笔记
  • 图说复变函数论重大错误:将无穷多各异平面误为同一面
  • Python常用脚本集锦
  • Linux下复制粘贴快捷键
  • neo4j浅析
  • [Linux] 进程控制之创建和终止
  • 【SQL50】day 1
  • Linux——Linux基础指令
  • 在 Spring Boot 中使用分布式事务时,如何处理不同数据源之间的事务一致性问题?
  • Java实战项目-基于SpringBoot的新能源汽车个性化推荐系统