1. 程式人生 > >演算法分析與設計課程05——514. Freedom Trail(Hard)

演算法分析與設計課程05——514. Freedom Trail(Hard)

給定一個字串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; } }