1138.字母板上的路径(LeetCode力扣)

ASCII码

a:97
z:122

移动规范:

1、当前位置在z(先上下移)
2、其他(先左右移)

目标字符串(target)整形(int)数组化

步骤
1、目标字符串转换为字符数组(toCharArray)
2、字符数组各元素减97转换为整形(int)数组

作用:
1、将小写字母重新编码(如0表示a)
2、方便对应字母板board(如字母板的k坐标为(2,0)可转化为2*5+0=10就对应重新的字母编码k=10)

字母坐标转化

如上k坐标(2,0)可转化为2*5+0=10 我们可以通过整除(/)和取余(%)获取字母对应坐标(行列) 字母k(10)(行列索引从零开始)(5是字母板每行最大值为5个)
10/5=2(第二行)
10%5=0(第零列)

思路

1、当前位置(开始时为a:(0,0))
2、下一个位置(目标字符串元素对应字母板的坐标(x,y))
3、根据移动规范决定移动顺序
4、根据移动顺序和行列差添加移动指令(最后加上'!')
5、修改当前位置为下一个位置,重新获取下一个位置
6、重复3456步骤,直到移动完成

代码

class Solution {

    // 指令序列is
    private StringBuilder is = new StringBuilder();

    // 内部类(记录位置的行和列)
    private class Loc{
        private int row;// 行
        private int col;// 列
        Loc(int row,int col){
            this.row = row;
            this.col = col;
        }
        int getRow(){
            return row;
        }
        int getCol(){
            return col;
        }
    }

    public String alphabetBoardPath(String target) {
        // 字符串长度
        int len = target.length();
        // 1、将字符串每个元素修改编码为int数组
        int[] targetInts = changeStringIntoInts(target,len);
        // 2、判断targetInts数组在字母板的位置
        // 2.1 当前位置(起始位置)
        Loc curLoc = new Loc(0,0);
        for(int i = 0;i < len;i++){
            // 2.1 下一个位置
            Loc nextLoc =  new Loc(targetInts[i]/5,targetInts[i]%5);
            // 3、添加指令序列(对比当前位置和下一个位置)
            addIs(nextLoc.getRow() - curLoc.getRow(),// 移动行数
                nextLoc.getCol() - curLoc.getCol(),// 移动列数
                curLoc.getRow());// 当前位置行数(判断是否是z)
            // 4、修改当前位置
            curLoc = nextLoc;
        }
        return is.toString();
    }

    // 将字符串每个元素修改编码为int数组
    private int[] changeStringIntoInts(String target, int len){
        // 1、切割target字符串为字符数组targetChars
        char[] targetChars = target.toCharArray();
        // 2、targetChars每个元素减97转化为int数组targetInts
        int[] targetInts = new int[len];
        for(int i = 0;i < len;i++){
            targetInts[i] = targetChars[i] - 97;
        }
        return targetInts;
    }

    // 添加指令序列(对比当前位置和下一个位置)
    private void addIs(int changeRow,int changeCol,int curLocRow){
        // 如果下一个位置不在z(26),就先左右移,z在第六行
        if(curLocRow == 5){
            // 1 添加上下移指令
            addUDLR(changeRow,'D','U');
            // 2 添加左右移指令
            addUDLR(changeCol,'R','L');
        }
        else{
            // 1 添加左右移指令
            addUDLR(changeCol,'R','L');
            // 2 添加上下移指令
            addUDLR(changeRow,'D','U');
        }
        // 添加'!'指令
        is.append('!');
    }
    // 添加上下左右指令
    private void addUDLR(int move,char c1,char c2){
        if(move < 0){
            c1 = c2;
            move *= -1;
        }
        for(int i = 0;i < move;i++){
            is.append(c1);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值