Leetcode 2977. Minimum Cost to Convert String II

本文介绍了如何解决LeetCode题目2977,涉及有向图的最短路径计算,字符串变换的最小成本分析,以及使用Floyd算法和动态规划的优化方法。作者提到通过剪枝和Trie树减少了时间复杂度,但代码仍然耗时较长。

1. 解题思路

这一题思路上和前一题差不多,还是先对给定的有向图求出其中任意两点间的最短距离,然后考察字符串的变换方式。

但是,这里相较于上一题的难度在于说,这里的有向图的变换节点不再单纯是字母了,因此组合更多了。

其次的话,由于变换的节点为不定长的字符串,因此对source字符串和target字符串的变换关系可以给出不同的拆分关系,可以有不同的cost,需要对其选择最小值。

但是,即便如此,思路上来说还是很直接的,上半部分本质上和上一题一模一样,用一个Floyd算法就能直接得到。

而关于后半部分,事实上更加简单,直接使用动态规划就行。

不过,实际在处理过程中,遇到了超时的问题,因此这里做了一些剪枝的优化操作,这部分还是比较零碎的:

  1. Floyd算法的算法复杂度是 O ( N 3 ) O(N^3) O(N3),因此我们需要对所有的节点进行一下去重,并且对第一层的节点提前求出了所有可能的中间节点的可能性,从而进一步进行了剪枝;
  2. 对于动态规划的部分,我们引入了一个trie树,使得遍历过程可以提前终止,将整体的算法复杂度从 O ( N 2 ) O(N^2) O(N2)大幅进行缩减。

但即便给出上述这些多少繁琐的剪枝操作,还是仅仅勉强通过了所有测试样例,耗时依然非常长,不知道其他大佬们是怎么处理的,看了一两个大佬们的解法,不过没有看懂就是了,唉……

2. 代码实现

给出python代码实现如下:

class Trie:
    def __init__(self):
        self.trie = {}
    
    def add_word(self, word):
        trie = self.trie
        for c in word:
            trie = trie.setdefault(c, {})
        trie["eos"] = ""

class Solution:
    def minimumCost(self, source: str, target: str, original: List[str], changed: List[str], cost: List[int]) -> int:
        n, m = len(source), len(original)
        
        costs = defaultdict(lambda: math.inf)
        for src, tgt, c in zip(original, changed, cost):
            costs[(src, tgt)] = min(c, costs[(src, tgt)])
        original = list(set(original))
        changed_set = set(changed)
        changed = list(changed_set)
        interval = [src for src in original if src in changed_set]
        for mid in interval:
            for src in original:
                for tgt in changed:
                    costs[(src, tgt)] = min(costs[(src, tgt)], costs[(src, mid)] + costs[(mid, tgt)])
        
        trie = Trie()
        for src in original:
            trie.add_word(src)

        @lru_cache(None)
        def dp(idx):
            if idx >= n:
                return 0
            ans = math.inf
            _trie = trie.trie
            src, tgt = "", ""
            for j in range(idx, n):
                src, tgt = src + source[j], tgt + target[j]
                if src == tgt:
                    ans = min(ans, dp(j+1))
                elif (src, tgt) in costs:
                    ans = min(ans, costs[(src, tgt)] + dp(j+1))
                if source[j] not in _trie:
                    break
                _trie = _trie[source[j]]
            return ans
        
        ans = dp(0)
        return ans if ans != math.inf else -1

提交代码评测得到:耗时16432ms,占用内存30.3MB。

内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值