演算法分析與設計課程05——514. Freedom Trail(Hard)
阿新 • • 發佈:2019-01-26
給定一個字串ring=”godding”和key=”gd”,ring按照下面方式放在圓盤上,對於key[0]即’g’字元,和12點鐘方向【即圓盤最上面】的字元相匹配,所以不用轉圓盤,按下圓中按鈕,記錄步驟1次,對於key[1]=’d’,12點鐘方向顯然不是’d’,所以可以逆時針轉圓盤,共2步將d轉到12點鐘方向,然後按下按鈕,記錄步驟2+1=3次,即總共找到key=”gd”共用了3+1=4個步驟。(實際上,’d’也可以順時針旋轉圓盤4步將d轉到12點鐘方向,按下共耗費5步驟,加上之前的1+5=6,而6>4,所以選用4)
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.
二、題目分析
這個我沒有太多想法,想用窮舉法來解決問題(這種解答方式在LeetCode裡超時了,但思想很簡單,結果也是對的)
每次尋找一個字元B,總會從一個字元A開始,可以從A的左邊到達B,也可以從A的右邊到達B,而到達B之後,B就是起始字元
從B開始,從B的左邊到達C,從B的右邊到達C
依次類推,直到找完key,這時有了很多結果,從結果當中選取最小的一個結果就是該問題的解。
三、原始碼
import java.util.Scanner;
import java.util.*;
public class Solution {
public static void main(String arg[])
{
String ring, key;
Scanner cin = new Scanner(System.in);
ring = cin.next();
key = cin.next();
Solution temp = new Solution();
System.out.println(temp.findRotateSteps(ring, key));
}
class RotateResult{
public int pos_start;
public int from_to_step;
public RotateResult(int pos_start, int from_to_step)
{
this.pos_start = pos_start;
this.from_to_step = from_to_step;
}
}
public RotateResult rotateRight(String ring, int pos_start, char cur_ch)//往右邊轉
{
int start = pos_start;
int index = ring.indexOf(cur_ch, start);
if(index != -1)
{
RotateResult result = new RotateResult(index, index - start + 1);
return result;
}
else
{
index = ring.indexOf(cur_ch);
RotateResult result = new RotateResult(index, ring.length() - start + index + 1);
return result;
}
}
public RotateResult rotateLeft(String ring, int pos_start, char cur_ch)//往左邊轉
{
int start = pos_start;
int index = -1;
for(int i = start; i >= 0; i --)
{
if(ring.charAt(i) == cur_ch)
{
index = i;
break;
}
}
if(index != -1)
{
RotateResult result = new RotateResult(index, start - index + 1);
return result;
}
else
{
for(int i = ring.length() - 1; i > start; i --)
if(ring.charAt(i) == cur_ch)
{
index = i;
break;
}
RotateResult result = new RotateResult(index, ring.length() - index + start + 1);
return result;
}
}
public class CurResult
{
public int start;
public int step;
public CurResult(int start, int step)
{
this.start = start;
this.step = step;
}
}
public void buildSet(LinkedList<CurResult> result_set, int step, String ring, int pos_start, char cur_ch)
{
RotateResult rightResult = rotateRight(ring, pos_start, cur_ch);
RotateResult leftResult = rotateLeft(ring, pos_start, cur_ch);
CurResult cur_result1 = new CurResult(rightResult.pos_start, rightResult.from_to_step + step);
CurResult cur_result2 = new CurResult(leftResult.pos_start, leftResult.from_to_step + step);
result_set.add(cur_result1);
result_set.add(cur_result2);
}
public int findRotateSteps(String ring, String key) {
LinkedList<CurResult> result_set = new LinkedList<CurResult>();//用於儲存結果集
char cur_ch;
for(int i = 0; i < key.length(); i ++)
{
cur_ch = key.charAt(i);
if(result_set.size() == 0)//初始化
{
CurResult c = new CurResult(0, 0);
result_set.add(c);
}
int set_size = result_set.size();
for(int j = 0; j < set_size; j ++)
{
CurResult cur_result = result_set.removeFirst();
int pos_start = cur_result.start;
int step = cur_result.step;
buildSet(result_set, step, ring, pos_start, cur_ch);
}
}
int theBiggest = Integer.MAX_VALUE;
int flag = 0;
for(int i = 0; i < result_set.size(); i ++)
if(result_set.get(i).step < theBiggest)
theBiggest = result_set.get(i).step;
return theBiggest;
}
}