【算法思考记录】动态规划入门!力扣2606. 找到最大开销的子字符串【Python3、动态规划】

这篇具有很好参考价值的文章主要介绍了【算法思考记录】动态规划入门!力扣2606. 找到最大开销的子字符串【Python3、动态规划】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原题链接


动态规划基本原理

动态规划(Dynamic Programming,简称 DP)是一种通过将原问题分解为相互重叠的子问题并只解决一次的方法来解决问题的算法优化技术。动态规划通常用于优化递归问题,通过存储子问题的解来避免重复计算,从而显著提高算法的效率。

基本思想

动态规划的基本思想是将原问题划分为若干个子问题,通过解决子问题得到原问题的解。在这个过程中,动态规划使用了最优子结构重叠子问题两个关键性质。

  1. 最优子结构:问题的最优解可以通过子问题的最优解来构造。即,全局最优解包含了所有局部最优解。

  2. 重叠子问题:在递归求解过程中,对于一些子问题的解会被多次使用。为了避免重复计算,我们可以将子问题的解存储起来,后续直接使用,这就是动态规划中的记忆化。

基本步骤

动态规划通常包含以下基本步骤:

  1. 定义状态:明确定义问题的状态,找出问题中具有变化的量,并将其表示为状态。状态是原问题和子问题中变化的量。

  2. 找到状态转移方程:建立状态之间的关系,即如何由小的子问题推导出大问题的解。状态转移方程是动态规划的核心。

  3. 初始化:设置问题的初始值,通常是最简单的情况,这是递归或迭代的终止条件。

  4. 递推计算:按照状态转移方程,从初始状态开始递推计算,直到计算出原问题的解。

  5. 解决原问题:得到原问题的解,这通常是在状态中已经计算得到的值。

应用领域

动态规划广泛应用于各个领域,包括但不限于:

  • 优化问题:如最短路径、最长子序列、背包问题等。
  • 计算问题:如斐波那契数列、组合数等。
  • 决策问题:如股票买卖、任务调度等。

总的来说,动态规划通过将复杂问题分解为简单的子问题,并有效地保存子问题的解,从而在时间和空间上实现了高效的问题求解。

找到最大开销的子字符串算法解析

问题描述

给定一个字符串 s,一个字符互不相同的字符串 chars 和一个长度与 chars 相同的整数数组 vals。子字符串的开销是一个子字符串中所有字符对应价值之和,空字符串的开销是 0。

字符的价值定义如下:

  • 如果字符不在字符串 chars 中,那么它的价值是它在字母表中的位置(下标从 1 开始)。
  • 如果字符在 chars 中的位置为 i,那么它的价值就是 vals[i]

问题要求返回字符串 s 的所有子字符串中的最大开销。

思路

题目要求找到最大开销的子字符串,我们可以使用动态规划的思路解决。在这里,我们使用一个一维数组 dp 来记录以字符串 s 的每一位结尾的最大开销。

状态定义

我们定义 dp[i] 为以字符串 s 的第 i 位结尾的最大开销。

状态转移

状态转移方程为 dp[i] = max(dp[i - 1] + char_val, char_val),其中 char_val 是第 i 个字符对应的开销值。

代码实现

class Solution:
    def maximumCostSubstring(self, s: str, chars: str, vals: List[int]) -> int:
        char_idx = {}
        for idx, char in enumerate(chars):
            char_idx[char] = idx
        n = len(s)
        dp = [0] * n
        dp[0] = vals[char_idx[s[0]]] if s[0] in char_idx else ord(s[0]) - ord('a') + 1
        ans = max(dp[0], 0)
        for i in range(1, n):
            new_char_val = vals[char_idx[s[i]]] if s[i] in char_idx else (ord(s[i]) - ord('a') + 1)
            dp[i] = max(dp[i - 1] + new_char_val, new_char_val)
            ans = max(ans, dp[i])

        return ans

示例分析

示例 1

s = "adaa"
chars = "d"
vals = [-1000]
solution = Solution()
result = solution.maximumCostSubstring(s, chars, vals)
print(result)  # Output: 2

解释:字符 “a” 和 “d” 的价值分别为 1 和 -1000。最大开销子字符串是 “aa”,它的开销为 1 + 1 = 2。2 是最大开销。

示例 2

s = "abc"
chars = "abc"
vals = [-1,-1,-1]
solution = Solution()
result = solution.maximumCostSubstring(s, chars, vals)
print(result)  # Output: 0

解释:字符 “a”,“b” 和 “c” 的价值分别为 -1,-1 和 -1。最大开销子字符串是 “”,它的开销为 0。0 是最大开销。

复杂度分析

时间复杂度

遍历字符串 s 一次,每次更新 dp[i] 的操作为 O(1),因此总时间复杂度为 O(n)。

空间复杂度

使用了额外的空间来存储 dp 数组和 char_idx 字典,因此空间复杂度为 O(n)。文章来源地址https://www.toymoban.com/news/detail-773153.html

到了这里,关于【算法思考记录】动态规划入门!力扣2606. 找到最大开销的子字符串【Python3、动态规划】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法】力扣【动态规划,LCS】1143. 最长公共子序列

    1143. 最长公共子序列 本文是对 LCS 这一 动态规划 模型的整理,以力扣平台上的算法题1143:最长公共子序列为模板题进行解析。 该题目要求计算两个字符串的最长公共子序列(Longest Common Subsequence,简称LCS)的长度。字符串的子序列是指在不改变字符顺序的情况下,通过删去

    2024年01月17日
    浏览(60)
  • 算法50:动态规划专练(力扣514题:自由之路-----4种写法)

    题目: 力扣514 : 自由之路  . - 力扣(LeetCode) 题目的详细描述,直接打开力扣看就是了,下面说一下我对题目的理解: 事例1: 1. ring的第一个字符默认是指向12点方向的,这一点很重要 2. key的第一个字符为g,而ring中首字符和末尾字符都为g。因此,必然存在选择首字符的g还

    2024年04月15日
    浏览(30)
  • 【算法】力扣【动态规划、状态机】309. 买卖股票的最佳时机含冷冻期

    309. 买卖股票的最佳时机含冷冻期 本文介绍解决力扣平台上第309号问题——“买卖股票的最佳时机含冷冻期”的算法。这是一个中等难度的问题,其核心是通过设计一个算法来计算在给定的股票价格数组 prices 下,能够获取的最大利润。股票价格数组 prices 中的每个元素 pric

    2024年01月18日
    浏览(49)
  • 力扣算法刷题Day39|动态规划:不同路径 I&II

    力扣题目:#62.不同路径 刷题时长:参考题解后10min 解题方法:动规 复杂度分析 时间O(m*n) 空间O(m*n) 问题总结 初始化二维数组的python语法:i 对应 m,j 对应n 二维遍历顺序,从上到下从左到右通过两层for循环实现,其中startindex应为1 本题收获 动规思路 确定dp数组及下标的含义

    2024年02月12日
    浏览(51)
  • 算法记录 | 48 动态规划

    思路: 1.确定dp数组(dp table)以及下标的含义: dp[i]:前 i 间房屋所能偷窃到的最高金额。 2.确定递推公式: dp[i] = max(dp[i - 2] + nums[i-1], dp[i - 1]) i间房屋的最后一个房子是nums[i−1]。 如果房屋数大于等于 2 间,则偷窃第 i−1 间房屋的时候,就有两种状态: 偷窃第 i−1 间房屋

    2024年02月05日
    浏览(37)
  • 算法学习记录:动态规划

    目录 前言: 背景知识: 正文:  什么是动态规划(更新中):  理解动态规划: 状态: 状态转移:  运用动态规划(分析步骤): 例题集(时间顺序)  1.蓝桥OJ 3820:混境之地5(DFS) 2.蓝桥OJ 216:地宫取宝(DFS) 3.蓝桥OJ 1536:数字三角形(迭代法) 4.蓝桥OJ 3367:破损的

    2024年01月25日
    浏览(46)
  • 力扣算法刷题Day42|动态规划:01背包问题 分割等和子集

    力扣题目:01背包问题(二维数组) 刷题时长:参考题解 解题方法:动态规划 + 二维dp数组 复杂度分析 时间 空间 问题总结 理解递推公式困难 本题收获 动规思路:两层for循环,第一层i遍历物品,第二层j枚举背包容量以内所有值 确定dp数组及下标的含义:dp[i][j] 表示从下标

    2024年02月13日
    浏览(62)
  • 算法记录 | Day46 动态规划

    思路: 1.确定dp数组以及下标的含义 dp[i] : 字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词 。 2.确定递推公式 如果 s[0: j] 可以拆分为单词(即 dp[j] == True ),并且字符串 s[j: i] 出现在字典中,则 dp[i] = True 。 如果 s[0: j] 不可以拆分为单词(即

    2024年02月02日
    浏览(39)
  • 算法记录 | Day38 动态规划

    对于动态规划问题,将拆解为如下五步曲 确定dp数组(dp table)以及下标的含义 确定递推公式 dp数组如何初始化 确定遍历顺序 举例推导dp数组 思路: 确定dp数组(dp table)以及下标的含义:dp[i]的定义为:第i个数的斐波那契数值是dp[i] 确定递推公式:状态转移方程 dp[i] = dp

    2023年04月22日
    浏览(44)
  • 算法记录 | Day55 动态规划

    思路: 1.确定dp数组(dp table)以及下标的含义: dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为 dp[i][j] 。 2.确定递推公式: if (s[i - 1] == t[j - 1]) t中找到了一个字符在s中也出现了, dp[i][j] = dp[i - 1][j - 1] + 1 if (s[i - 1] != t[j - 1]) 相当于t要

    2024年02月03日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包