问题描述

In the video game Fallout 4, the quest "Road to Freedom" requires players to reach a metal dial called the "Freedom Trail Ring", and use the dial to spell a specific keyword in order to open the door.

Given a string ring, which represents the code engraved on the outer ring and another string key, which represents the keyword needs to be spelled. You need to find the minimum number of steps in order to spell all the characters in the keyword.

Initially, the first character of the ring is aligned at 12:00 direction. You need to spell all the characters in the string key one by one by rotating the ring clockwise or anticlockwise to make each character of the string key aligned at 12:00 direction and then by pressing the center button.

At the stage of rotating the ring to spell the key character key[i]:

  1. You can rotate the ring clockwise or anticlockwise one place, which counts as 1 step. The final purpose of the rotation is to align one of the string ring's characters at the 12:00 direction, where this character must equal to the character key[i].

  2. If the character key[i] has been aligned at the 12:00 direction, you need to press the center button to spell, which also counts as 1 step. After the pressing, you could begin to spell the next character in the key (next stage), otherwise, you've finished all the spelling.

Example:


Input: ring = "godding", key = "gd"
Output: 4
Explanation:
For the first key character 'g', since it is already in place, we just need 1 step to spell this character.
For the second key character 'd', we need to rotate the ring "godding" anticlockwise by two steps to make it become "ddinggo".
Also, we need 1 more step for spelling.
So the final output is 4.

Note:

  1. Length of both ring and key will be in range 1 to 100.
  2. There are only lowercase letters in both strings and might be some duplcate characters in both strings.
  3. It's guaranteed that string key could always be spelled by rotating the string ring.

算法分析:

该题需要使用动态规划算法进行计算
先声明一个二维的动态规划表 int [][] dp=new int[key.length()][ring.length()]; dp[i][j] 的值表示转动到 key 中的第 i 个字符在 ring 中第 j 个位置时总共需要的转动 step (不包括按下 button 键的 step )。
状态转移方程:
dp[i][j]=min(dp[i][j],dp[i-1][k]+min(abs(j-k),ring.leng()-abs(j-k))).
该方程中,i 表示当前考察的 key 中的字符在 key 中的下标,j 表示当前考察的字符在 ring 中的下标,k 表示上一个考察的字符在 ring 中的下标。

Java 算法实现:

public class Solution {
public int findRotateSteps(String ring, String key) {
ArrayList<Integer>[] list=new ArrayList[128];
char ch;
for(int i=0;i<ring.length();i++){//统计ring中所有的字符在ring中的下标
ch=ring.charAt(i);
if(list[ch]==null){
list[ch]=new ArrayList<Integer>();
}
list[ch].add(i);
} int ringLoop=ring.length();
int[][]dp=new int[key.length()][ring.length()];
for(Integer index:list[key.charAt(0)]){//对 key 中第一个字符在 ring 中的位置进行记录
dp[0][index]=Math.min(index, ringLoop-index);
}
char former=key.charAt(0),cur;
for(int i=1;i<key.length();i++){//动态规划算法
cur=key.charAt(i);
for(Integer indexCur:list[cur]){//遍历当前考察的字符在 ring 中的位置
dp[i][indexCur]=Integer.MAX_VALUE;
for(Integer indexFormer:list[former]){//遍历上一个字符在 ring 中的位置
int distance=Math.abs(indexCur-indexFormer);//当前考察的字符与上一个考察的字符在 ring 中的距离
dp[i][indexCur]=Math.min(dp[i][indexCur], dp[i-1][indexFormer]+Math.min(distance,ringLoop-distance));
}
}
former=cur;
}
int mindist=Integer.MAX_VALUE;
int depth=key.length()-1;// key 中最后一个字符的下标
for(Integer lastIndex:list[key.charAt(depth)]){//遍历 key 中最后一个字符在 ring 中的所有位置
if(mindist>dp[depth][lastIndex]){ //找到到达 key 中最后一个字符所需的最小 step 数
mindist=dp[depth][lastIndex];
}
}
return mindist+key.length(); //总的 step 数要包括按下 button 键的次数
}
}

最新文章

  1. HTML之:fieldset——一个不常用的HTML标签
  2. [ORACLE错误]ORA-00054:resource busy and acquire with nowait specified解决方法
  3. Ubuntu 14.10 下卸载MySQL
  4. UIToolbar swift
  5. Oracle中建立物化视图报错
  6. Android HttpClient get传递数组
  7. oschina 建站系统
  8. angularJS socket
  9. pom 的scope标签分析
  10. SEO-发信息注意的问题
  11. 如何为Rails作贡献:例增加rich_text field generators
  12. 一言难尽的js变量提升
  13. hdu2087 剪花布条
  14. 【Leetcode】收集
  15. win7下一劳永逸地解决触控板禁用的问题
  16. StringUtils.isEmpty和StringUtils.isBlank用法和区别
  17. yum 安装mysql, yum安装指定版本的mysql
  18. stenciljs 学习十 服务器端渲染
  19. 第二章 Socket用法详解
  20. Java基础-IO流对象之字符缓冲流(BufferedWriter与BufferedReader)

热门文章

  1. spark中资源调度任务调度
  2. Mac 10.12安装流量监控软件Magican
  3. (转)WordPress常用模板函数 修改或自制WordPress主题必备
  4. HUE配置文件hue.ini 的Spark模块详解(图文详解)(分HA集群和HA集群)
  5. Types方法之isSameType-isSuperType-isSubType
  6. JavaScript数据结构-18.图结构广度优先和最短路径
  7. ognl,jstl,struts2标签中符号#,$,%的用法
  8. JAVA泛型——逆变
  9. Android中数据的保存
  10. iOS开源项目周报0216