[Leetcode/Scala] 688. “马”在棋盘上的概率

本文介绍了一种计算骑士在N*N棋盘上,经过K步随机移动后仍留在棋盘内的概率的方法。通过模拟骑士的移动,利用flatMap、groupBy和filter等函数,有效地解决了内存溢出的问题,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

已知一个 NxN 的国际象棋棋盘,棋盘的行号和列号都是从 0 开始。即最左上角的格子记为 (0, 0),最右下角的记为 (N-1, N-1)。

现有一个 “马”(也译作 “骑士”)位于 (r, c) ,并打算进行 K 次移动。

如下图所示,国际象棋的 “马” 每一步先沿水平或垂直方向移动 2 个格子,然后向与之相垂直的方向再移动 1 个格子,共有 8 个可选的位置。

Alt

现在 “马” 每一步都从可选的位置(包括棋盘外部的)中独立随机地选择一个进行移动,直到移动了 K 次或跳到了棋盘外面。

求移动结束后,“马” 仍留在棋盘上的概率。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/knight-probability-in-chessboard
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


题目是很简单的,只需要模拟点的映射过程。
即点(x,y, prob) => {(xk,yk, prob / 8 )} (k = 0 ~ 7)
之后做flatten。// 这一步的过程是flatMap
由于每次一个点变成8个点,那么点的数量是指数级的,k较大的时候内存会溢出。
所以,我们需要合并相同点的概率,即(x,y, p1) 和(x,y,p2) => (x,y, p1+ p2)。// group后对概率进行累加
每一次我们得到点如果越界,我们可以直接丢弃// 即filter过程。

所以,总的来说这道题很好的结合了,flatMap,groupby,filter的使用。
代码就很简单了

object Solution {
    def knightProbability(N: Int, K: Int, r: Int, c: Int): Double = {
        def f(l:List[(Int, Int, Double)],k:Int):Double = 
        if(k == 0) l.map{case ( x, y, z) => z}.sum else 
        f(
            l
            .flatMap {case (x, y, z) => 
                List((x+2, y+1, z/8), (x+2, y-1, z/8), (x-2, y+1, z/8), (x-2, y-1, z /8), 
                     (x+1, y+2, z/8), (x+1, y-2, z/8), (x-1, y-2, z/8), (x-1, y+2, z /8))}
            .groupBy {case (x, y, z) => (x, y)}
            .toList
            .map{case (k, v) => (k._1, k._2, v.map(_._3).sum)}
            .filterNot{case (x, y, z) =>  x < 0 || y < 0 || x >= N || y >= N},
            k-1
        )
    f(List((r,c,1)), K)
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值