字符串的 append 操作,矩阵中两点曼哈顿距离最短,求解《1138. 字母板上的路径》

2023-02-12 11:07:46
字符串的 append 操作,矩阵中两点曼哈顿距离最短,求解《1138. 字母板上的路径》

例题

1138. 字母板上的路径

我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。
在本题里,字母板为board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"],如下所示。 我们可以按下面的指令规则行动:
如果方格存在,'U' 意味着将我们的位置上移一行;
如果方格存在,'D' 意味着将我们的位置下移一行;
如果方格存在,'L' 意味着将我们的位置左移一列;
如果方格存在,'R' 意味着将我们的位置右移一列;
'!' 会把在我们当前位置 (r, c) 的字符 board[r][c] 添加到答案中。
(注意,字母板上只存在有字母的位置。)
返回指令序列,用最小的行动次数让答案和目标 target 相同。你可以返回任何达成目标的路径。
示例 1: 输入:target = "leet"
输出:"DDR!UURRR!!DDD!"
示例 2:
输入:target = "code"
输出:"RR!DDRR!UUL!R!"
提示: 1 <= target.length <= 100
target 仅含有小写英文字母。

答案

曼哈顿距离

var alphabetBoardPath = function(target) {
  let x = 0, y = 0
  const n = target.length, r = []
  for (let i = 0; i < n; i++) {
    const index = target.charCodeAt(i) - 'a'.charCodeAt()
    const [dx, dy] = [index / 5 | 0, index % 5]
    while (x > dx) {
      r.push('U')
      x--
    }
     while (y > dy) {
      r.push('L')
      y--
    }

    while (x < dx) {
      r.push('D')
      x++
    }
    while (y < dy) {
      r.push('R')
      y++
    }
    r.push('!')
    x = dx
    y = dy
  }
  return r.join('')
}
function alphabetBoardPath(target: string): string {
  const n = target.length, r = []
  let x = 0, y = 0
  for (let i = 0; i < n; i++) {
    const index = target.charCodeAt(i) - 'a'.charCodeAt(0)
    const dx = index / 5 | 0, dy = index % 5
    while (x > dx) {
      r.push('U')
      x--
    }
    while (y > dy) {
      r.push('L')
      y--
    }
    while (x < dx) {
      r.push('D')
      x++
    }
    while (y < dy) {
      r.push('R')
      y++
    }
    r.push('!')
    x = dx
    y = dy
  }
  return r.join('')
};
class Solution {
  function alphabetBoardPath($target) {
    $x = 0;
    $y = 0;
    $r = '';
    $n = strlen($target);
    for ($i = 0; $i < $n; $i++) {
      $index = ord($target[$i]) - ord('a');
      $dx = $index / 5 | 0;
      $dy = $index % 5;
      while ($x > $dx) {
        $r .= 'U';
        $x--;
      }
      while ($y > $dy) {
        $r .= 'L';
        $y--;
      }
      while ($x < $dx) {
        $r .= 'D';
        $x++;
      }
      while ($y < $dy) {
        $r .= 'R';
        $y++;
      }
      $r .= '!';
      $x = $dx;
      $y = $dy;
    }
    return $r;
  }
}
func alphabetBoardPath(target string) string {
  r := []byte{}
  x, y := 0, 0
  for _, char := range target {
    dx, dy := int(char - 'a') / 5, int(char - 'a') % 5
    for x > dx {
      r = append(r, 'U')
      x--
    }
    for y > dy {
      r = append(r, 'L')
      y--
    }
    for x < dx {
      r = append(r, 'D')
      x++
    }
    for y < dy {
      r = append(r, 'R')
      y++
    }
    r = append(r, '!')
    x, y = dx, dy
  }
  return string(r)
}
class Solution {
  public String alphabetBoardPath(String target) {
    StringBuilder r = new StringBuilder();
    int n = target.length();
    int x = 0, y = 0;
    for (int i = 0; i < n; i++) {
      char c = target.charAt(i);
      int dx = (c - 'a') / 5;
      int dy = (c - 'a') % 5;
      while (x > dx) {
        r.append('U');
        x--;
      }
      while (y > dy) {
        r.append('L');
        y--;
      }
      while (x < dx) {
        r.append('D');
        x++;
      }
      while (y < dy) {
        r.append('R');
        y++;
      }
      r.append('!');
      x = dx;
      y = dy;
    }
    return r.toString();
  }
}
public class Solution {
  public string AlphabetBoardPath(string target) {
    StringBuilder r = new StringBuilder();
    int x = 0, y = 0;
    foreach(char c in target) {
      int dx = (c - 'a') / 5;
      int dy = (c - 'a') % 5;
      while (x > dx) {
        r.Append('U');
        x--;
      }
      while (y > dy) {
        r.Append('L');
        y--;
      }
      while (x < dx) {
        r.Append('D');
        x++;
      }
      while (y < dy) {
        r.Append('R');
        y++;
      }
      r.Append('!');
      x = dx;
      y = dy;
    }
    return r.ToString();
  }
}
class Solution {
public:
  string alphabetBoardPath(string target) {
    string r;
    int x = 0, y = 0;
    for (char c : target) {
      int dx = (c - 'a') / 5;
      int dy = (c - 'a') % 5;
      if (x > dx) r.append(x - dx, 'U');
      if (y > dy) r.append(y - dy, 'L');
      if (x < dx) r.append(dx - x, 'D');
      if (y < dy) r.append(dy - y, 'R');
      r.push_back('!');
      x = dx;
      y = dy;
    }
    return r;
  }
};
char * alphabetBoardPath(char * target){
  int n = strlen(target);
  char* r = malloc(sizeof(char) * 10 * n);
  int p = 0, x = 0, y = 0;
  for (int i = 0; i < n; i++) {
    char c = target[i];
    int dx = (c - 'a') / 5;
    int dy = (c - 'a') % 5;
    while (x > dx) {
      r[p++] = 'U';
      x--;
    }
    while (y > dy) {
      r[p++] = 'L';
      y--;
    }
    while (x < dx) {
      r[p++] = 'D';
      x++;
    }
    while (y < dy) {
      r[p++] = 'R';
      y++;
    }
    r[p++] = '!';
    x = dx;
    y = dy;
  }
  r[p] = '\0';
  return r;
}
class Solution:
  def alphabetBoardPath(self, target: str) -> str:
    r = []
    x, y = 0, 0
    for char in target:
      index = ord(char) - ord('a')
      dx, dy = index // 5, index % 5
      if x > dx: r.append('U' * (x - dx))
      if y > dy: r.append('L' * (y - dy))
      if x < dx: r.append('D' * (dx - x))
      if y < dy: r.append('R' * (dy - y))
      r.append('!')
      x, y = dx, dy
    return ''.join(r)

顺序遍历,求解《1790. 仅执行一次字符串交换能否使两个字符串相等》
顺序遍历,求解《1790. 仅执行一次字符串交换能否使两个字符串相等》
递归,分治,栈,顺序遍历深度,4 解法求解《856. 括号的分数》
递归,分治,栈,顺序遍历深度,4 解法求解《856. 括号的分数》
用哈希映射数据结构,分割字符串为数组,截取字符串,求解《811. 子域名访问计数》
用哈希映射数据结构,用 split / explode / stirngs.Split / strtok 分割字符串为数组,substring / substr / 指针截取字符串,求解《811. 子域名访问计数》