This is a graph problem, and the problem try to find the shortest path. So BFS is just right solution, the following is my first solution.

It works but TLE. Why? Because I tried to search path from all four quadrants. 

The time complexity is O(max(|x|, |y|)2.

    public int minKnightMoves(int x, int y) {
        Set<String> visited = new HashSet<>();
        int[][] dirs = {{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1},{-1,2}};
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0,0});
        visited.add("0,0");
        int steps = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i=0;i<size;i++){
                int[] sqr = queue.poll();
                if(sqr[0]==x && sqr[1]==y){
                    return steps;
                }
                for(int[] dir: dirs){
                    int nextX = dir[0]+sqr[0];
                    int nextY = dir[1]+sqr[1];
                    if(nextX>300 || nextX<-300 || nextY>300 || nextY<-300)
                        continue;
                    String temp = nextX+","+nextY;
                    if(visited.contains(temp))
                        continue;
                    queue.offer(new int[]{nextX, nextY});
                    visited.add(temp);
                }
            }
            steps++;
        }
        return steps;
    }

 

Since the most part of the shortest path should be within the same quadrant of the (x,y), we can have the following solution.

This soltuion can beat about 20%

    public int minKnightMoves(int x, int y) {
        x = Math.abs(x);  //within one quadrant
        y = Math.abs(y);
        Set<String> visited = new HashSet<>();
        int[][] dirs = {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}};
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0, 0});
        visited.add("0,0");
        int steps = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] sqr = queue.poll();
                if (sqr[0] == x && sqr[1] == y) {
                    return steps;
                }
                for (int[] dir : dirs) {
                    int nextX = dir[0] + sqr[0];
                    int nextY = dir[1] + sqr[1];
                    if (nextX < -1 || nextY < -1)    //if x=1, y=1, either nextX or nextY need to be -1
                        continue;
                    String temp = nextX + "," + nextY;
                    if (visited.contains(temp))
                        continue;
                    queue.offer(new int[]{nextX, nextY});
                    visited.add(temp);
                }
            }
            steps++;
        }
        return steps;
    }

Because we use String Type to tell visited, it is slow and occupy lot of memories.

We can have the following solution, using boolean[][] to tell visited which beat about 80%

    public int minKnightMoves(int x, int y) {
        x = Math.abs(x);
        y = Math.abs(y);
        boolean[][] visited = new boolean[302][302];
        int[][] dirs = {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}};
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0, 0});
        visited[1][1] = true;
        int steps = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] sqr = queue.poll();
                if (sqr[0] == x && sqr[1] == y) {
                    return steps;
                }
                for (int[] dir : dirs) {
                    int nextX = dir[0] + sqr[0];
                    int nextY = dir[1] + sqr[1];
                    if (nextX < -1 || nextY < -1 || nextX > 300 || nextY > 300)  //if x=1, y=1, either nextX or nextY need to be -1
                        continue;
                    if (visited[nextX + 1][nextY + 1])
                        continue;
                    queue.offer(new int[]{nextX, nextY});
                    visited[nextX + 1][nextY + 1] = true;
                }
            }
            steps++;
        }
        return steps;
    }

 

posted on 2022-03-05 09:03  阳光明媚的菲越  阅读(31)  评论(0编辑  收藏  举报