LeetcodeMedium- [インタビューの質問13.ロボットの可動範囲]

座標[0,0]から座標[m-1、n-1]まで、地面にm行n列のグリッドがあります。ロボットは座標[0、0]のグリッドから開始し、一度に1つのグリッドを左、右、上、下に移動できます(グリッドの外に移動できません)。また、行と列の座標を入力できません。数字の合計は、 kの格子。たとえば、kが18の場合、3 + 5 + 3 + 7 = 18であるため、ロボットは正方形[35、37]に入ることができます。しかし、3 + 5 + 3 + 8 = 19であるため、正方形[35、38]に入ることができません。ロボットが到達できるグリッドはいくつですか?

 

例1:

入力:m = 2、n = 3、k = 1
出力:3


例2:

入力:m = 3、n = 1、k = 0
出力:1


ヒント:

1 <= n、m <= 100
0 <= k <= 20

出典:LeetCode
リンク:https ://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
著作権は控除ネットワークに属しています。商用転載の正式な許可書に連絡し、非商用転載の出典を明記してください。

ディレクトリ

アイデア1:ディープサーチ(dfs)

アイデア2:Guangsuo(bfs)

アイデア3:再帰


アイデア1:ディープサーチ(dfs)

開始点(0、0)から始めて、4方向に検索すると、継続できる条件は、座標の数がK以下であることです。

従来のディープサーチは4つの方向にありますが、この質問は次のように最適化できます。

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        # 暴力
        self.cnt = 0
        self.n = n
        self.m = m
        self.k = k
        self.visit = [[0]*n for _ in range(m)]
        self.dx = [0, 1] # 优化为只:向右、向下
        self.dy = [1, 0]
        
        self.visit[0][0] = 1
        self.dfs(0, 0)

        return self.cnt
    
    def dfs(self, x, y):
        ti = x
        tj = y
        t = 0
        while ti > 0:
            t += ti % 10
            ti = ti // 10
        while tj > 0:
            t += tj % 10
            tj = tj // 10
        if t <= self.k:
            self.cnt += 1
        else:
            return 
        for i in range(2):
            xx = x + self.dx[i]
            yy = y + self.dy[i]
            if 0 <= xx < self.m and 0 <= yy < self.n and self.visit[xx][yy] == 0:
                self.visit[xx][yy] = 1
                self.dfs(xx, yy)
        

アイデア2:Guangsuo(bfs)

Guangsouはキューを使用して実装されており、この質問ではsetを使用して重複排除します。

def digitsum(n):
    ans = 0
    while n:
        ans += n % 10
        n //= 10
    return ans

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        from queue import Queue
        q = Queue()
        q.put((0, 0))
        s = set()
        while not q.empty():
            x, y = q.get()
            if (x, y) not in s and 0 <= x < m and 0 <= y < n and digitsum(x) + digitsum(y) <= k:
                s.add((x, y))
                q.put((x, y + 1))
                q.put((x + 1, y))
        return len(s)

    

アイデア3:再帰

def digitsum(n):
    ans = 0
    while n:
        ans += n % 10
        n //= 10
    return ans

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        s = set([(0, 0)])
        for i in range(m):
            for j in range(n):
                if ((i-1,j) in s or (i,j-1) in s) and digitsum(i) + digitsum(j) <= k:
                    s.add((i, j))
        return len(s)

 

公開された314元の記事 ウォン称賛22 ビュー20000 +

おすすめ

転載: blog.csdn.net/qq_39451578/article/details/105427334