每日一题 力扣514自由之路

2024-01-29 14:28
文章标签 力扣 每日 自由 514

本文主要是介绍每日一题 力扣514自由之路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

514. 自由之路

题目描述:

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

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

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

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

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

示例1:

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

示例 2:

输入: ring = "godding", key = "godding"
输出: 13

提示:

  • 1 <= ring.length, key.length <= 100
  • ring 和 key 只包含小写英文字母
  • 保证 字符串 key 一定可以由字符串  ring 旋转拼出

思路:

动态规划,大神思路在代码区!

代码:

cv 的大佬Ikaruga的代码:

class Solution {
public:int findRotateSteps(string ring, string key) {vector<int> pos[26];//记录ring里每个字符都在哪 godding里是 g在 0 6, d在 2 3for (int i = 0; i < ring.size(); i++) {pos[ring[i] - 'a'].push_back(i);}vector<vector<int>> dp(key.size(), vector<int>(ring.size(), INT_MAX));//dp[i][j]的定义: 在匹配key中第i个字母的时候,使用ring中第j个位置,所需要的操作。for (int i = 0; i < key.size(); i++) {for (auto j : pos[key[i] - 'a']) {//j是key[i] 在环内的位置if (i == 0) {//key的第一个字母, 不需要考虑任何前面的次数//只需要计算 指针从0 转到 j 的操作次数 再加上 1 , 选择当前, 就是总操作数dp[i][j] = min(dp[i][j], 0 + clac(ring.size(), 0, j) + 1);continue;}//当i非0的时候, 需要看一下之前字母的操作次数//k 就是前一个字母的位置for (auto k : pos[key[i - 1] - 'a']) {//非第一个的字母, 需要看一下从前面的字母,怎么转移来是操作数最小的。//比如那个老哥给的例子,dp[0][1] = 2, dp[0][8] = 3,//然后匹配第二个字母的时候,dp[1][3] = min(dp[0][1] + 从1转到3 + 1, dp[0][8] + 从 8 转到3 + 1)dp[i][j] = min(dp[i][j], dp[i - 1][k] + clac(ring.size(), k, j) + 1);}}}return *min_element(dp.back().begin(), dp.back().end());}//计算从 指针在a 到 字母所在位置b 最少需要转多少次int clac(int len, int a, int b) {return min((len + a - b) % len, (len + b - a) % len);}
};

参考循环队列的出入队,以及求队长的操作,可以得到从某一位置到另一位置的最近步数:
min((len + a - b) % len, (len + b - a) % len);

再来一个Python:

class Solution:def findRotateSteps(self, ring: str, key: str) -> int:#先用一个哈希表存放ring中各个字母的索引hs = dict()for i in range(len(ring)):if ring[i] not in hs:hs[ring[i]] = [i]else:hs[ring[i]].append(i)#初始化dp数组,包括初始化第一行m,n = len(ring),len(key)dp = [float('inf')]*mfor q in hs[key[0]]:dp[q] = min(q,m-q)+1for i in range(1,n):#分为两种情况:1.正在处理的字母与上一个字母不同;2.正在处理的字母与上一个字母相同;if key[i]!=key[i-1]:for p in hs[key[i-1]]:for j in hs[key[i]]:dp[j] = min(dp[j],min(abs(j-p),m-abs(j-p))+dp[p]+1)dp[p] = float('inf')else:for j in hs[key[i]]:# tmp = float('inf')# for p in hs[key[i-1]]:#     tmp = min(tmp,min(abs(j-p),m-abs(j-p))+dp[p]+1)# dp[j] = tmpdp[j]+=1return min(dp)

这篇关于每日一题 力扣514自由之路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/657212

相关文章

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

两数之和--力扣1

两数之和 题目思路C++代码 题目 思路 根据题目要求,元素不能重复且不需要排序,我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中,使用目标值减去当前循环的nums[i],得到差值,如果我们在map中能够找到这个差值,就说明存在两个整数的和为目标值。 如果没有找到,就将当前循环的nums[i]以及下标i放入map中,以便后续查

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

力扣第347题 前K个高频元素

前言 记录一下刷题历程 力扣第347题 前K个高频元素 前K个高频元素 原题目: 分析 我们首先使用哈希表来统计数字出现的频率,然后我们使用一个桶排序。我们首先定义一个长度为n+1的数组,对于下图这个示例就是长度为7的数组。为什么需要一个长度为n+1的数组呢?假如说总共有三个数字都为1,那么我们需要把这个1放在数组下标为3的位置,假如说数组长度为n,对于这个例子就是长度为3,那么它的

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结,删除链表节点问题使用到列表,哈希表,递归比较容易超时,我觉得使用计数排序比较稳,处理起来也不是很难。 1. 力扣3217:从链表中移除在数组中的节点 1.1 题目: 给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后,返回修改后的链表的头节点。 示例 1: 输入: nums = [1,2,3], head = [1,2,3,

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调

创建一个大的DIV,里面的包含两个DIV是可以自由移动

创建一个大的DIV,里面的包含两个DIV是可以自由移动 <body>         <div style="position: relative; background:#DDF8CF;line-height: 50px"> <div style="text-align: center; width: 100%;padding-top: 0px;"><h3>定&nbsp;位&nbsp;

力扣接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 示例 2: 输入:height