当前位置:首页>java>Leetcode编程算法随笔(难度1882 Floyed算法 动态规划)2976. 转换字符串的最小成本 I

Leetcode编程算法随笔(难度1882 Floyed算法 动态规划)2976. 转换字符串的最小成本 I

  • 2026-10-11 11:32:18
Leetcode编程算法随笔(难度1882 Floyed算法 动态规划)2976. 转换字符串的最小成本 I

题目

https://leetcode.cn/problems/minimum-cost-to-convert-string-i/description/

给你两个下标从 0开始的字符串 source 和 target ,它们的长度均为 n 并且由 小写 英文字母组成。

另给你两个下标从 0 开始的字符数组 original 和 changed ,以及一个整数数组 cost ,其中 cost[i] 代表将字符 original[i] 更改为字符 changed[i] 的成本。

你从字符串 source开始。在一次操作中,如果存在任意下标j满足cost[j] == z  、original[j] == x以及changed[j] == y。你就可以选择字符串中的一个字符x并以z的成本将其更改为字符y 。

返回将字符串 source 转换为字符串 target 所需的最小成本。如果不可能完成转换,则返回 -1 。

注意,可能存在下标 i 、j 使得 original[j] == original[i] 且 changed[j] == changed[i] 。

  • 1 <= source.length == target.length <= 105
  • source target 均由小写英文字母组成
  • 1 <= cost.length== original.length == changed.length <= 2000
  • original[i] changed[i] 是小写英文字母
  • 1 <= cost[i] <= 106
  • original[i] != changed[i]

示例 :

输入:
source = "abcd", 
target = "acbe", 
original = ["a","b","c","c","e","d"], 
changed = ["b","c","b","e","b","e"], 
cost = [2,5,5,1,2,20]
输出:28
解释:
将字符串 "abcd" 转换为字符串 "acbe" :
 - 更改下标 1 处的值 'b' 为 'c' ,成本为 5 。 
- 更改下标 2 处的值 'c' 为 'e' ,成本为 1 。
 - 更改下标 2 处的值 'e' 为 'b' ,成本为 2 。 
- 更改下标 3 处的值 'd' 为 'e' ,成本为 20 。 
产生的总成本是 5 + 1 + 2 + 20 = 28 。 可以证明这是可能的最小成本。
主要包含
#Floyed算法 复杂度O(n^3) 适合计算所有点两两之间的最短路
#动态规划细节~ 状态不一定是点状的状态
#遇事不决先排序 有序对于算法是个好东西
思路
1. 
读完题目,可以看到,问题的关键点是得到从一个字母到另一个字母的最小代,最小路径问题。
2.
考虑到数据范围,特别是小写字母只有26个,是可以写一个bfs的。考试的时候,或者实际使用的时候,能解决就好,平时学习,则扩展知识更好些。所以还是来看一下Floyed的思路。
3.
动态规划中常见的关键点是找子问题 以及如何 状态转移。Floyed算法的状态转移从不同角度去看,理解起来似乎不一样。
以下的思路,大概可以算是从简单和基本的概念找规律的方法
不考虑距离,一个点到另外一个点,怎么才能过去?
的或者直接过去最短,或者要经过了其它点,这两个大类是涵盖所有的,而第二大类会出现,途经点个数不一样的情况。
将大问题分解为子问题是可以的
从小问题合成大问题也一样可行
如果已知了所有点两两之间的直接相连最短距离(有可能会出现两个点之间有多条连接)
那么,就可以通过遍历,逐步计算
两个点之间通过一个其它的点,
通过两个其它的点
通过...个其它的点
一直到通过n-2个其它的点
这确实是个方法,但它的复杂度有点高,任意两点的直接距离就是O(n^2)
它们之间的连接可以通过C(n-2,1)的一个中间,C(n-2,2)的两个中间点,C(n-2,3)的三个中间点而连接...
更换思路
有序化或者说特殊化
能不能给没有顺序的考虑加入顺序 也是将粗略的思路细化的一种形式
1. 
任意两个点间的直接连接距离
一个点到自己的距离或者跳过或者按0处理都可以
2. 
任意两个点间只以点a 为中间点的距离
那么起点到a的距离必须是它们两个点间最短的距离,a到终点也是
3. 
只以点a,b 为中间点的距离
这个情况仔细一点,
从0到1 与从1到2 ,或者从n到n+1是飞船值得仔细陈述清楚的步骤
设起点s,终点e
注意现在已经考虑了全部的两个点的直接连接
以及通过a点的连接 s-a-e , s-a-b , b-a-e (先不考虑方向)
s-a-s 类型的不用考虑,因为边的权重>=0
注意
考虑s到e 且通过b,a 两点做中间点的时候,a,b是顺次考虑的
或者说现在计算dis(s,e)最小可能数值的时候,要比较的已知的 dis(s,e) 与 dis(s,b)+ dis(b,e)
这个dis(s,b)是考虑过s,b的直接连接与s经过a 到b 的
常用的写法是用f(s, e, b) 表示这个状态,s,e 可以换做任意的n个点
而b表示的不是一个点的状态,而是包含了一系列点的,
因此才在前面说状态不一定是点状的状态,注意到这个应该对于动态规划问题有帮助
只以点a,b,c为中间点的距离
...
以所有点为中间点的距离
理清晰
dis(a, b, i+1)= min( dis(a, b, i) , dis(a, i, i) +dis(i, b,i))
这个,就可以代码了
辅助简单的图示,看看有没有什么遗漏或者发现
以这个图为例,
另外的一些有帮助的东西
在考虑新的问题时候,思路适当慢一点,多发散,少过快的得出结论
数学归纳法 从 n 到n+1 都做了什么?
x+1个点与x个点之间的关系是什么?也就是常说的状态转移,什么样子的转移可以有更好的复杂度?
更具象一点,比如考虑从一个城市到另一个城市的旅行,中转点不断加多的情况
代码
这段代码还可以有剪枝优化和以及空间复杂度上的优化
BFS思路的代码

最新文章

随机文章