【Leetcode】1138. Alphabet Board Path

题目地址:

https://leetcode.com/problems/alphabet-board-path/

在这里插入图片描述
给定如图所示的棋盘,左上角坐标视为 ( 0 , 0 ) (0,0) (0,0),向下和向右是正方向。给定一个长 n n n小写英文字符串 s s s,要求返回一个棋盘中的路径,路径中'U', 'D', 'L', 'R'分别代表上下左右走一步,而'!'代表取当前位置的字符,使得路径走完恰好就取到了整个字符串 s s s。返回长度最小的任意一条路径。路径不能走出界。

两个字母之间的最短路径其实是确定的(每一步的方向可能不同,但如果按照上下左右这四个方向的先后次序走,则路径是唯一的),主要需要注意的是出发或到达的点是'z'的时候,路径要特殊构造一下(因为不能出界)。代码如下:

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Solution {
    public String alphabetBoardPath(String target) {
    	// 存一下每个字母的坐标
        Map<Character, int[]> map = new HashMap<>();
        for (char ch = 'a', i = 0; ch <= 'z'; ch++, i++) {
            map.put(ch, new int[]{i / 5, i % 5});
        }
        
        int[] cur = {0, 0};
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < target.length(); i++) {
            char ch = target.charAt(i);
            int[] next = map.get(ch);
            sb.append(buildPath(cur, next, map)).append('!');
            cur = next;
        }
        
        return sb.toString();
    }
    
    private String buildPath(int[] cur, int[] next, Map<Character, int[]> map) {
        if (Arrays.equals(cur, next)) {
            return "";
        }
        
        char x = 0, y = 0;
        x = cur[0] < next[0] ? 'D' : 'U';
        y = cur[1] < next[1] ? 'R' : 'L';
        StringBuilder sb = new StringBuilder();
        // 如果起点是z,那么路径一定要先上下再左右;否则先左右后上下
        if (Arrays.equals(map.get('z'), cur)) {
            move(sb, Math.abs(cur[0] - next[0]), x);
            move(sb, Math.abs(cur[1] - next[1]), y);
        } else {
            move(sb, Math.abs(cur[1] - next[1]), y);
            move(sb, Math.abs(cur[0] - next[0]), x);
        }
        
        return sb.toString();
    }
    
    private void move(StringBuilder sb, int step, char l) {
        for (int i = 0; i < step; i++) {
            sb.append(l);
        }
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值