LC.688. Knight Probability in Chessboard

LC.688. Knight Probability in Chessboard_第1张图片

class Solution1(object):
    def knightProbability(self, N, K, r, c):
        """
        递归, 如果跳出直接return 0 ,如果K==0根据是否跳出return 0 或 1
        否则 递归八种情况
        用memo记录已经计算过的路径
        """
        self.N = N
        self.memo = {}
        return self.DFS(r,c,K)

    def neighbor(self, x, y):
        direction = [(x-2, y+1), (x-1, y+2), (x+1, y+2), (x+2, y+1), (x+2, y-1), (x+1, y-2), (x-1,y-2), (x-2, y-1)]
        for xx, yy in direction:
            yield xx,yy

    def DFS(self, x,y, K):
        if x < 0 or x >= self.N or y < 0 or y >= self.N:
            return 0
        else:
            if K == 0:
                return 1
            else:
                key = str(x) + "-" + str(y) + "-" + str(K)
                if key not in self.memo:
                    result = 0
                    for xx, yy in self.neighbor(x,y):
                        result += self.DFS(xx,yy, K-1)
                    self.memo[key] = 0.125 * result
                return self.memo[key]

class Solution(object):
    # 我们用dp[i][j]数组表示在第n步的时候,到i,j点的路径的条数,用其乘以 0.125^n, 即n步后到能达到该点的概率
    def knightProbability(self, N, K, r, c):
        def neighbor(x, y):
            direction = [(x - 2, y + 1), (x - 1, y + 2), (x + 1, y + 2), (x + 2, y + 1), (x + 2, y - 1), (x + 1, y - 2),
                         (x - 1, y - 2), (x - 2, y - 1)]
            for xx, yy in direction:
                yield xx, yy
        dp = [[0]*N for i in range(N)]
        dp[r][c] = 1
        for step in range(K):
            tmp = [[0]*N for i in range(N)]
            for i in range(N):
                for j in range(N):
                    for xx,yy in neighbor(i, j):
                        if 0 <= xx < N and 0 <= yy < N:
                            tmp[xx][yy] += dp[i][j]
            dp = tmp
        result = 0
        for line in dp:
            result += sum(line)
        return result * pow(0.125, K)

你可能感兴趣的:(LeetCode)