leetcode 514 自由之路 维特比算法

这篇博客介绍了如何使用动态规划和维特比算法来解决LeetCode上的514题——自由之路。博主首先探讨了错误的贪心策略,然后详细阐述了正确解题方法,即利用维特比算法找到全局最优解。
摘要由CSDN通过智能技术生成

思路一(错误):贪心
此题要做出来,只需要知道,当前字母到下一个字母最短位置。由于字母可以重复,每次选最近的字母的贪心策略可以产生局部最优,但全局的步数并不是最少的。

class Solution:
    def get_step(self, idx1, idx2, length):
        min0, max0 = min(idx1, idx2), max(idx1, idx2)
        return min(max0-min0, length-max0+min0)

    def findRotateSteps(self, ring: str, key: str) -> int:
        MAX = 2000
        char2pos = {}
        for i in range(len(ring)):
            char = ring[i]
            if char in char2pos:
                char2pos[char].append(i)
            else:
                char2pos[char] = [i]
        total_steps, current_pos = 0, 0
        for char in key:
            min_step, min_pos = MAX, 0
            for pos in char2pos[char]:
                step = self.get_step(pos, current_pos, len(ring))
                if step < min_step:
                    min_step = step
                    min_pos = pos
            current_pos = min_pos
            total_steps += min_step + 1
        
        return total_steps

思路二(正确):动态规划
通过上一种思路,可以想到维特比算法是一种很好的策略。在每一层根据上一层所有点的最优解,可以得到每个点的最优解。代码如下:

class Solution:
    def get_step(self, idx1, idx2, length):
        min0, max0 = min(idx1, idx2), max(idx1, idx2)
        return min(max0-min0, length-max0+min0)

    def findRotateSteps(self, ring: str, key: str) -> int:
        MAX = 2000
        char2pos = {}
        for i in range(len(ring)):
            char = ring[i]
            if char in char2pos:
                char2pos[char].append(i)
            else:
                char2pos[char] = [i]
        posNsteps = [(0,0)]
        for char in key:
            new_list = []
            for end_pos in char2pos[char]:
                min_step = MAX
                for tup in posNsteps:
                    start_pos, prev_step = tup
                    step = self.get_step(start_pos, end_pos, len(ring))
                    if prev_step + step < min_step:
                        min_step = step + prev_step + 1
                new_list.append((end_pos, min_step))
            posNsteps = new_list

        minx = MAX
        for tup in posNsteps:
            _, step = tup
            minx = min(minx, step)
        
        return minx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值