leetcode514. 自由之路【线性dp】

 原题链接:leetcode514. 自由之路

题目描述

电子游戏“辐射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 旋转拼出

解题思路:

我们需要利用一个在转盘上的环形字符串ring通过转动若干次使得转出key字符串,可以顺时针或者逆时针转,首先我们要拼出字符串key,拼出字符串key就是要依次让key的每一个字符依次指向十二点钟方向,要拼出key字符串,肯定先从key的第一个字符从前往后依次转出来,转出key[i]这种字符的最少转动次数只和前一个字符key[i-1]有关,由于key[i-1]在环形字符串中可能出现多次,而且key[i-1]可能需要用到若干次,说明实际上如果暴力搜索所有情况是存在重复计算的,看到重复计算我们就可以想到dp进行优化了,因为dp就是用来优化重复计算的呀,实际上到这里我们就可以知道这是一个很明显的线性dp了,下面定义状态进行dp处理即可。

状态定义:

定义f[i][j]表示第i步走到ring[j]的最少转动次数。

状态转移:

pos[i]存储i+'a'在ring中出现的位置

第0步走到key[0],看key[0]在ring中的出现位置进行处理,j表示pos[key[0-'a']],后面的+1表示最后按中心按钮

f[0][j]=0+d(ring.size(),0,j)+1;      

key[i]从key[i-1]转移过来,k枚举的就是key[i-1]在ring中出现的位置,用i-1步走到k来更新i步走到j

f[i][j]=f[i-1][k]+d(ring.size(),k,j)+1

最终答案:

要拼出key字符串,所以最终答案肯定是走了key.size()-1步,然后最后停在ring[j]=key[key.size()-1]的位置。

时间复杂度:不妨设m=key.size(),n=ring.size(),第一维枚举步数,时间为O(m),第二维枚举key[i]在ring中出现的位置,时间为O(n),第三维枚举key[i-1]在ring中出现的位置,时间为O(n),最终时间复杂度为O(m*(n^2)).

空间复杂度:dp数组f为二维,空间复杂度为O(m*n)。

cpp代码如下:

const int N=110;
int f[N][N];
class Solution {
    int d(int n,int a,int b)  //求a->b的往左走和往右走哪种方式距离更短
    {
        if(a>b)swap(a,b);
        return min(b-a,n-b+a);
    }
public:
    int findRotateSteps(string ring, string key) {
        vector<int>pos[26];  //pos[i]存储i+'a'在ring中出现的位置
        for(int i=0;i<ring.size();i++){
            pos[ring[i]-'a'].push_back(i);
        }

        //初始化
        for(int i=0;i<key.size();i++)
            for(int j=0;j<ring.size();j++)
                f[i][j]=1e9;
        //dp
        for(int i=0;i<key.size();i++)
            for(auto j:pos[key[i]-'a'])
            {
                if(i==0){  //第0步肯定是从位置0走到位置j
                    f[i][j]=min(f[i][j],0+d(ring.size(),0,j)+1);
                    continue;
                }
                //从key[i-1]在ring中出现的位置走到key[i]在ring中出现的位置
                for(auto k:pos[key[i-1]-'a']){
                    f[i][j]=min(f[i][j],f[i-1][k]+d(ring.size(),k,j)+1);
                }
            }

        /*
            要拼出字符串ring,我们走的步数肯定是ring.size()-1,最终会停在
            ring[i]==key[key.size()-1]的位置,但是由于这里我们的dp处理
            不会更新无效状态,所以我们直接按照下述更新方法对所有位置直接
            更新即可,因为一些无效位置dp处理的过程中没有被更新,所以这样
            更新并不会影响答案。
        */
        int ans=1e9;
        for(int i=0;i<ring.size();i++)
            ans=min(ans,f[key.size()-1][i]);
        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/358260.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CHS_03.2.3.2_2+进程互斥的硬件实现方法

CHS_03.2.3.2_2进程互斥的硬件实现方法 知识总览中断屏蔽方法TestAndSet指令Swap指令 知识回顾 进程互斥的四种软件实现方法 知识总览 这个小节我们会介绍另外的三种进程互斥的硬件实现方法 那么 这个小节的学习过程当中 大家需要注意理解各个方法的原理 并且要稍微的了解各个…

OpenGL ES 渲染 NV21、NV12 格式图像有哪些“姿势”?

使用2个纹理实现 NV21 格式图像渲染 前文提到渲染 NV21 格式图像需要使用 2 个纹理,分别用于保存 Y plane 和 UV plane 的数据,然后在片段着色器中分别对 2 个纹理进行采样,转换成 RGB 数据。 OpenGLES 渲染 NV21或 NV12 格式图像需要用到 GL_LUMINANCE 和 GL_LUMINANCE_A…

更改远程桌面网关端口和远程Web应用程序端口

很多玩Home-Lab的小伙伴会使用远程桌面网关&#xff08;Remote Desktop Gateway&#xff09;来安全远程家庭内网的计算机&#xff0c;但由于国内电信法律法规的原因&#xff0c;普通家庭宽带并不能使用默认的443端口&#xff08;TCP&#xff09;和3391端口&#xff08;UDP&…

Shell中sed编辑器

1.简介 sed是一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据&#xff0c;这些命令要么从命令行中输入&#xff0c;要么存储在一个 命令文本文件中。 2.sed编辑器的工作流程 sed…

【高效开发工具系列】Wolfram Alpha

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

linux离线升级openssh方法

检查openssh版本&#xff1a; 升级前openssh 版本为7.4 openssl 版本为1.0.2k Openssh9.6 所需openssl >1.1.1 因此openssl也需要升级。 为了防止升级失败&#xff0c;无法使用SSH登录&#xff0c;首先安装telnet 预防。查看是否安装了telnet 客户端及服务 未安装tel…

npm安装下载修改镜像源

问题描述一 npm install 时&#xff0c;报错&#xff1a;npm ERR! network request to https://registry.npmjs.org/postcss-pxtorem failed, reason: connect ETIMEDOU&#xff0c;这是因为默认npm安装会请求国外的镜像源&#xff0c;导致下载缓慢容易断开请求下载失败的 np…

高效集成|聚道云软件连接器实现薪人薪事与每刻报销无缝对接

一、客户介绍 某石油天然气有限公司是一家在石油天然气领域拥有深厚实力和丰富经验的公司。在技术方面&#xff0c;该公司始终保持领先地位&#xff0c;拥有高素质、专业化的技术团队&#xff0c;不断引进和吸收国际先进技术&#xff0c;加强自主创新&#xff0c;为公司的持续…

C语言菜鸟入门·判断语句(if语句、if...else语句、嵌套if语句)详细介绍

目录 1. if语句 2. if...else语句 3. if...else if...else 语句 4. 嵌套if语句 C 语言把任何非零和非空的值假定为 true&#xff0c;把零或 null 假定为 false。 语句描述if语句一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。if...else语句一个 if 语句 后可跟…

绿色荧光素标记半胱氨酸,FITC-Cysteine,可以用来标记和追踪细胞内的蛋白质

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;FITC半胱氨酸&#xff0c;绿色荧光素标记半胱氨酸&#xff0c;FITC Cysteine 一、基本信息 产品简介&#xff1a;FITC Crystal green fluorescent labeled cysteine is a widely used biological tracer with high …

海外云手机开辟企业跨境电商新道路

近几年&#xff0c;海外云手机为跨境电商、海外媒体引流、游戏行业等互联网领域注入了蓬勃活力。对于国内跨境电商而言&#xff0c;在亚马逊及其他平台上&#xff0c;短视频引流和社交电商营销成为最为有效的流量来源。如何通过海外云手机的助力&#xff0c;在新兴社交平台为企…

28 python快速上手

索引和函数及存储过程 1. 索引1.1 索引原理1.1.1 非聚簇索引&#xff08;mysiam引擎&#xff09;1.1.2 聚簇索引&#xff08;innodb引擎&#xff09; 1.2 常见索引1.2.1 主键和联合主键索引1.2.2 唯一和联合唯一索引1.2.3 索引和联合索引案例&#xff1a;博客系统 1.3 操作表1.…

​ArcGIS Pro 如何批量删除字段

在某些时候&#xff0c;我们得到的图层属性表内可能会有很多不需要的字段&#xff0c;如果挨个去删除会十分的麻烦&#xff0c;对于这种情况&#xff0c;我们可以使用工具箱内的字段删除工具批量删除&#xff0c;这里为大家介绍一下使用方法&#xff0c;希望能对你有所帮助。 …

Unity3d Cinemachine篇(三)— FreeLook

文章目录 前言一、使用FreeLook制造第三人称跟随效果1. 创建一个游戏物体2. 创建FreeLook相机4. 完成 前言 上一期我们简单的使用了Dolly CamerawithTrack相机&#xff0c;这次我们来使用一下FreeLook 一、使用FreeLook制造第三人称跟随效果 1. 创建一个游戏物体 游戏物体比较…

类与对象下篇

前言 在类与对象上篇我们讲解了类的基础框架&#xff0c;中篇我们讲解了类的基本内容&#xff0c;下篇我们将补充类的一些零散知识点。 一、构造函数的初始化&#xff08;初始值&#xff09;列表 构造函数&#xff1a;创建类对象时自动调用&#xff0c;给对象中各个成员变量一…

多模态大模型综述整理

论文&#xff1a;MM-LLMs: Recent Advances in MultiModal Large Language Models 论文地址&#xff1a; https://arxiv.org/pdf/2401.13601.pdf 表1&#xff1a;26种主流多模态大型语言模型&#xff08;MM-LLMs&#xff09;概要 输入到输出模态&#xff08;I→O&#xff09;…

[React源码解析] Fiber (二)

在React15及以前, Reconciler采用递归的方式创建虚拟Dom, 但是递归过程不可以中断, 如果组件的层级比较深的话, 递归会占用线程很多时间, 那么会造成卡顿。 为了解决这个问题, React16将递归的无法中断的更新重构为异步的可中断更新, Fiber架构诞生。 文章目录 1.Fiber的结构2…

MySQL前百分之N问题--percent_rank()函数

PERCENT_RANK()函数 PERCENT_RANK()函数用于将每行按照(rank - 1) / (rows - 1)进行计算,用以求MySQL中前百分之N问题。其中&#xff0c;rank为RANK()函数产生的序号&#xff0c;rows为当前窗口的记录总行数 PERCENT_RANK()函数返回介于 0 和 1 之间的小数值 selectstudent_…

Ubuntu22.04 网络图标突然消失

本来好好的&#xff0c;突然就发现没有网络了&#xff0c;图标也不见了。 特别是Ubuntu虚拟机&#xff0c;容易出现此问题。 修复办法 1. sudo service network-manager stop2. sudo rm /var/lib/NetworkManager/NetworkManager.state3. sudo service network-manager start到…

通过Nacos权重配置,模拟微服务金丝雀发布效果(不停机部署)

在微服务项目迭代的过程中&#xff0c;不可避免需要上线&#xff1b;上线对应着部署&#xff0c;或者升级部署&#xff1b;部署对应着修改,修改则意味着风险。 传统的部署都需要先停止旧系统&#xff0c;然后部署新系统&#xff0c;之后需要对新系统进行全面的功能测试&#xf…