算法分析与设计课程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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值