美文网首页
Leetcode骑士问题

Leetcode骑士问题

作者: 专职跑龙套 | 来源:发表于2021-05-02 00:51 被阅读0次

关于我的 Leetcode 题目解答,代码前往 Github:https://github.com/chenxiangcyr/leetcode-answers


LeetCode题目:935. Knight Dialer
The chess knight has a unique movement, it may move two squares vertically and one square horizontally, or two squares horizontally and one square vertically (with both forming the shape of an L). The possible movements of chess knight are shown in this diagaram:

A chess knight can move as indicated in the chess diagram below:

image

We have a chess knight and a phone pad as shown below, the knight can only stand on a numeric cell (i.e. blue cell).

image

Given an integer n, return how many distinct phone numbers of length n we can dial.

You are allowed to place the knight on any numeric cell initially and then you should perform n - 1 jumps to dial a number of length n. All jumps should be valid knight jumps.

DP 算法,Golang 实现:

const mod = 1000000007

func knightDialer(n int) int {
    // key is the target position, value is the source postion which can jump to target position
    jumps := map[int][]int {
        -1: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
        0: {4, 6},
        1: {6, 8},
        2: {7, 9},
        3: {4, 8},
        4: {0, 3, 9},
        5: {},
        6: {0, 1, 7},
        7: {2, 6},
        8: {1, 3},
        9: {2, 4},
    }
    
    // dp[i][j]: distinct jumps to reach number j after jumps i times
    dp := make([][]int, n + 1)
    for i := range dp {
        dp[i] = make([]int, 10)
        for j := range dp[i] {
            dp[i][j] = -1
        }
    }
    
    return solve(n, -1, jumps, &dp)
}

func solve(n int, target int, jumps map[int][]int, dp *[][]int) int{
    if n == 0 {
        return 1
    }
    
    if target != -1 && (*dp)[n][target] != -1 {
        return (*dp)[n][target]
    }
    
    count := 0
    for _, source := range jumps[target] {
        count = (count + solve(n - 1, source, jumps, dp)) % mod
    }
    
    if target != -1 {
     (*dp)[n][target] = count
    }
    return count
}

LeetCode题目:688. Knight Probability in Chessboard
On an n x n chessboard, a knight starts at the cell (row, column) and attempts to make exactly k moves. The rows and columns are 0-indexed, so the top-left cell is (0, 0), and the bottom-right cell is (n - 1, n - 1).

A chess knight has eight possible moves it can make, as illustrated below. Each move is two cells in a cardinal direction, then one cell in an orthogonal direction.

image

Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there.

The knight continues moving until it has made exactly k moves or has moved off the chessboard.

Return the probability that the knight remains on the board after it has stopped moving.

Example 1:
Input: n = 3, k = 2, row = 0, column = 0
Output: 0.06250
Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board.
From each of those positions, there are also two moves that will keep the knight on the board.
The total probability the knight stays on the board is 0.0625.

Example 2:
Input: n = 1, k = 0, row = 0, column = 0
Output: 1.00000

Constraints:

  • 1 <= n <= 25
  • 0 <= k <= 100
  • 0 <= row, column <= n

DP 算法,Golang 实现:

var dir = [8][2]int{{2, -1}, {2, 1}, {-2, -1}, {-2, 1}, {1, 2}, {-1, 2}, {1, -2}, {-1, -2}}

func compute(N, K, r, c int, dp map[[3]int]float64) float64 {
    if r < 0 || c < 0 || r >= N || c >= N {
        return 0
    }
    if K == 0 {
        return 1
    }
    if val, ok := dp[[3]int{K, r, c}]; ok {
        return val
    }
    var out float64
    for _, v := range dir {
        out += compute(N, K - 1, r + v[0], c + v[1], dp) / 8.0
    }
    dp[[3]int{K, r, c}] = out
    return out
}

func knightProbability(N int, K int, r int, c int) float64 {
    dp := make(map[[3]int]float64)
    return compute(N, K, r, c, dp)
}

LeetCode题目:1197. Minimum Knight Moves
In an infinite chess board with coordinates from -infinity to +infinity, you have a knight at square [0, 0].

A knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction.

image

Return the minimum number of steps needed to move the knight to the square [x, y]. It is guaranteed the answer exists.

Example 1:
Input: x = 2, y = 1
Output: 1
Explanation: [0, 0] → [2, 1]

Example 2:
Input: x = 5, y = 5
Output: 4
Explanation: [0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]

BFS 算法,Java 实现:

class Solution {
    public int minKnightMoves(int x, int y) {
        x = Math.abs(x);
        y = Math.abs(y);
        
        if (x == 0 && y == 0) {
            return 0;
        }
        
        // BFS
        Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
        Set<Pair<Integer, Integer>> visited = new HashSet<>();
        
        queue.offer(new Pair(0, 0));
        visited.add(queue.peek());
        
        int[][] dirs = new int[][]{{2, 1}, {-2, 1}, {2, -1},
                {-2, -1}, {1, 2}, {-1, 2}, {1, -2}, {-1, -2}};
        int level = 0;
        
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                Pair<Integer, Integer> parent = queue.poll();
                for (int[] dir : dirs) {
                    int newX = Math.abs(parent.getKey() + dir[0]);
                    int newY = Math.abs(parent.getValue() + dir[1]);
                    
                    if (newX == x && newY == y) {
                        return level + 1;
                    }
                    
                    Pair<Integer, Integer> child = new Pair(newX, newY);
                    if (!visited.contains(child)) {
                        visited.add(child);
                        queue.add(child);
                    }
                }
            }
            level++;
        }
        return level;
    }
}

相关文章

  • Leetcode骑士问题

    关于我的 Leetcode 题目解答,代码前往 Github:https://github.com/chenxia...

  • 算法总览

    1.动态规划 1.leetcode 402:移除k位数字2.leetcode 935骑士拨号器3.leetcode...

  • Swap Nodes in Pairs

    标签: C++ 算法 LeetCode 链表 每日算法——leetcode系列 问题 Swap Nodes in ...

  • Combination Sum II

    标签: C++ 算法 LeetCode DFS 每日算法——leetcode系列 问题 Combinatio...

  • LeetCode-218-天际线问题

    LeetCode-218-天际线问题 218. 天际线问题[https://leetcode-cn.com/pro...

  • leetcode22 括号匹配

    leetcode刷题笔记 leetcode22 问题描述:Given n pairs of parentheses...

  • Divide Two Integers

    标签: C++ 算法 LeetCode 每日算法——leetcode系列 问题 Divide Two Integ...

  • First Missing Positive

    标签: C++ 算法 LeetCode 数组 每日算法——leetcode系列 问题 First Missing...

  • Valid Sudoku

    Valid Sudoku 标签: C++ 算法 LeetCode 每日算法——leetcode系列 问题 Val...

  • Next Permutation

    标签: C++ 算法 LeetCode 数组 每日算法——leetcode系列 问题 Next Permuta...

网友评论

      本文标题:Leetcode骑士问题

      本文链接:https://www.haomeiwen.com/subject/exzzrltx.html