【Leetcode 514】自由之路 —— 动态规划

这篇具有很好参考价值的文章主要介绍了【Leetcode 514】自由之路 —— 动态规划。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

514. 自由之路

电子游戏“辐射4”中,任务 “通向自由” 要求玩家到达名为 “Freedom Trail Ring” 的金属表盘,并使用表盘拼写特定关键词才能开门。

给定一个字符串ring,表示刻在外环上的编码;给定另一个字符串key,表示需要拼写的关键词。您需要算出能够拼写关键词中所有字符的最少步数。

最初,ring的第一个字符与12:00方向对齐。您需要顺时针或逆时针旋转ring以使key的一个字符在12:00方向对齐,然后按下中心按钮,以此逐个拼写完key中的所有字符。

旋转ring拼出key字符key[i]的阶段中:

您可以将ring顺时针或逆时针旋转一个位置,计为1步。旋转的最终目的是将字符串ring的一个字符与12:00方向对齐,并且这个字符必须等于字符key[i]
如果字符key[i]已经对齐到12:00方向,您需要按下中心按钮进行拼写,这也将算作1步。按完之后,您可以开始拼写key的下一个字符(下一阶段), 直至完成所有拼写。

示例 1:

【Leetcode 514】自由之路 —— 动态规划,Leetcode,leetcode,动态规划,java

输入: ring = “godding”, key = “gd”
输出: 4
解释:
对于 key 的第一个字符 ‘g’,已经在正确的位置, 我们只需要1步来拼写这个字符。
对于 key 的第二个字符 ‘d’,我们需要逆时针旋转 ring “godding” 2步使它变成 “ddinggo”。
当然, 我们还需要1步进行拼写。
因此最终的输出是 4。

示例 2:

输入: ring = “godding”, key = “godding”
输出: 13

题目分析

经典动态规划问题,更多案例可见 Leetcode 动态规划详解

【Leetcode 514】自由之路 —— 动态规划,Leetcode,leetcode,动态规划,java

我们可以使用动态规划解决本题,解题思路:

  1. 状态定义:
    • dp[i][j] 表示 key 的第 i 个字符, ring 的第 j 个字符与 12:00 方向对齐的最少步数
    • pos[i] 表示字符 i 在 ring 中出现的位置集合,用来加速计算转移的过程
  2. 状态转移方程:枚举上一次与12:00方向对齐的位置k,此次需要从位置k旋转到位置j

d p [ i ] [ j ] = min ⁡ k ∈ p o s [ k e y [ i − 1 ] ] d p [ i − 1 ] [ k ] + m i n a b s ( j − k ) , n − a b s ( j − k ) + 1 dp[i][j]= \displaystyle\min_k∈pos[key[i−1]] {dp[i−1][k] + min{abs(j − k), n − abs(j − k)} + 1} dp[i][j]=kminpos[key[i1]]dp[i1][k]+minabs(jk),nabs(jk)+1

​> min{abs(j − k), n − abs(j − k)} + 1从位置k旋转到位置j的最少步数

  1. 初始状态dp[0][i] = min{i, n - i} + 1,最终答案为 min ⁡ i = 0 n − 1 d p [ m − 1 ] [ i ] \displaystyle\min_i=0^n-1 {dp[m-1][i]} imin=0n1dp[m1][i]

动态规划一般用于求解具有重叠子问题和最优子结构的问题,例如最长公共子序列、背包问题、最短路径等。重叠子问题指的是在求解问题的过程中,多次用到相同的子问题,最优子结构指的是问题的最优解可以通过子问题的最优解来构造文章来源地址https://www.toymoban.com/news/detail-825720.html

class Solution {
    public int findRotateSteps(String ring, String key) {
        int n = ring.length(), m = key.length();
        // 字符 i 在 ring 中出现的位置集合,用来加速计算转移的过程
        List<Integer>[] pos = new List[26];
        for (int i = 0; i < 26; i++) {
            pos[i] = new ArrayList<Integer>();
        }
        for (int i = 0; i < n; i++) {
            pos[ring.charAt(i) - 'a'].add(i);
        }
        int[][] dp = new int[m][n];
        for (int i = 0; i < m; i++) {
            Arrays.fill(dp[i], Integer.MAX_VALUE);
        }
        for (int i : pos[key.charAt(0) - 'a']) {
            dp[0][i] = Math.min(i, n - i) + 1;
        }
        for (int i = 1; i < m; i++) {
            for (int j : pos[key.charAt(i) - 'a']) {
                for (int k : pos[key.charAt(i - 1) - 'a']) {
                    dp[i][j] = Math.min(dp[i][j], dp[i - 1][k] + Math.min(Math.abs(j - k), n - Math.abs(j - k)) + 1);
                }
            }
        }
        return Arrays.stream(dp[m - 1]).min().getAsInt();
    }
}

到了这里,关于【Leetcode 514】自由之路 —— 动态规划的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【leetcode刷题之路】初级算法(2)——链表+树+排序和搜索+动态规划

    3.1 【链表】删除链表中的节点 https://leetcode.cn/problems/delete-node-in-a-linked-list/ 给出的就是要删除的那个节点,直接前后移动就行了。 3.2 【双指针】删除链表的倒数第 N 个结点 https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ 利用双指针left和right,首先让right遍历n个节点,再让两

    2024年02月10日
    浏览(48)
  • 动态规划02 自由之路[C++]

       图源:文心一言 leedcode每日一题,提供了常规解法及其详细解释,供小伙伴们参考~🥝🥝 第1版:在力扣新手村刷题的记录~🧩🧩 方法一:递归调用,可以运行,但是不能通过较长的测试用例 失败 ~ 方法二:动态规划,普遍适用的方法~ 编辑: 梅头脑🌸 审核: 文心一言

    2024年02月22日
    浏览(37)
  • leetcode877. 石子游戏(动态规划-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/stone-game Alice 和 Bob 用几堆石子在做游戏。一共有偶数堆石子,排成一行;每堆都有 正 整数颗石子,数目为 piles[i] 。 游戏以谁手中的石子最多来决出胜负。石子的 总数 是 奇数 ,所以没有平局。 Alice 和 Bob 轮流进行,Alic

    2024年02月10日
    浏览(56)
  • leetcode63. 不同路径 II(动态规划-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/unique-paths-ii 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。

    2024年02月11日
    浏览(47)
  • leetcode300. 最长递增子序列(动态规划-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/longest-increasing-subsequence 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序

    2024年02月15日
    浏览(42)
  • leetcode1143. 最长公共子序列-动态规划(java)

    leetcode1143. 最长公共子序列 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/longest-common-subsequence 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串: 它是由原字

    2024年01月19日
    浏览(43)
  • Java 动态规划 Leetcode 740. 删除并获得点数

    对于该题的题目分析,已经代码分析都一并写入到了代码注释中

    2024年02月10日
    浏览(56)
  • leetcode416. 分割等和子集(动态规划-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/partition-equal-subset-sum 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums = [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。

    2024年02月11日
    浏览(36)
  • Java 动态规划 Leetcode 213. 打家劫舍 II

    代码展示:         该题其实是Java 动态规划 面试题 17.16. 按摩师的变种,增加了一个首尾是相邻的条件,而我们解决该题也要用到链接的这道题的思想,可以先去看一下上面这篇博客 此题可以采用动态规划的方法进行解决,根据解决动态规划题目的5大步骤进行逐步分析

    2024年02月13日
    浏览(39)
  • Java动态规划LeetCode1137. 第 N 个泰波那契数

             方法1:通过动态规划解题,这道题也是动态规划的一道很好的入门题,因为比较简单和容易理解。 代码如下:         动态规划的解题步骤分为5步                 1.状态表示                 2.状态转移方程                 3.初始化                 4.填表

    2024年02月13日
    浏览(47)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包