力扣刷题日记-面试题 LCP 03. 机器人大冒险

90 阅读2分钟
  • 这题有个技巧,就是算出指令一轮内所有涉及的点,放在set存放,如果目标在这些点中被命中,说明可以到达,
  • 这些点我用二进制存储

js版本:

/**
 * @param {string} command
 * @param {number[][]} obstacles
 * @param {number} x
 * @param {number} y
 * @return {boolean}
 */
var robot = function(command, obstacles, x, y) {
  let X = 0
  let Y = 0
  let set = new Set() // 用来存储一轮所涉及到的所有的点
  set.add(0)
  let cArr = command.split('')
  for(let c of cArr) {
    X += c == 'R' ? 1 : 0;
    Y += c == 'U' ? 1 : 0;
    set.add((X << 10) | Y)
  }
  // 不考虑任何额外的点,机器人能不能到达(x,y)
  if(!meet(x,y,X,Y,set)) {
    return false
  }
  for(let ob of obstacles) {
    if(ob[0] <= x && ob[1] <=y && meet(ob[0],ob[1],X,Y,set)){
      return false
    }
  }
  return true
};
function meet(x,y,X,Y,set) {
  if(X == 0) {
    return x == 0
  }
  if(Y == 0) {
    return y == 0
  }
  // js版本这里要记得取整数,不然出错
  let atLeast = Math.min(parseInt(x / X),parseInt(y / Y));
  let rx = x - atLeast * X;
  let ry = y - atLeast * Y;
  return set.has((rx << 10) | ry)
}

// test
let command = "UURRUUU"
let obstacles = [[4, 5], [6, 1], [7, 10], [9, 1], [1, 1], [5, 0], [2, 8]]
let x = 946
let y = 2365
robot(command, obstacles, x, y)

java版本:

package class51;
import java.util.Arrays;
import java.util.HashSet;

// leetcode题目: https://leetcode-cn.com/problems/programmable-robot/

public class LCP_0003_Robot {
  public static boolean robot1(String command,int[][] obstacles,int x, int y) {
    int X = 0;
    int Y = 0;
    HashSet<Integer> set = new HashSet<>();
    set.add(0);
    for(char c : command.toCharArray()) {
      X += c == 'R' ? 1 : 0;
      Y += c == 'U' ? 1 : 0;
      set.add((X << 10) | Y)
    }
    // 不考虑任何额外的点,机器人能不能到达(x,y)
    if(!meet1(x,y,X,Y,set)) {
      return false
    }
    for(int[] ob : obstacles) {
      if(ob[0] <= x && ob[1] <= y && meet1(ob[0],ob[1],X,Y,set)) {
        return false
      }
    }
    return true
  }
  // 一轮以内,X,往右走几个单位.Y,往上一共有几个单位
  // set 一轮以内的所有可能
  // (x,y) 要去的点
  // 机器人从(0,0)能不能走到(x,y)
  

  public static boolean meet1(int x,int y,int X,int Y,HashSet<Integer> set) {
    if(X == 0) {
      return x == 0
    }
    if(Y == 0) {
      return y == 0
    }
    // 至少要几轮
    int atLeast = Math.min(x / M, y / Y)
    // 经历过最少轮数后,x剩下多少
    int rx = x - atLeast * X;
    // 经历过最少轮数后,y剩下多少
    int ry = y - atLeast * Y;
    return set.contains((rx << 10) | ry)
  }
}