[剑指Offer] Day 14: Searching and Backtracking

Authored by Tony Feng

Created on April 25th, 2022

Last Modified on April 25th, 2022

Task 1 - Q13. 机器人的运动范围

Question

地上有一个mn列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

Solution 1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution: # BFS
    def movingCount(self, m: int, n: int, k: int) -> int:
        grid = [[0 for _ in range(n)] for _ in range(m)]
        q, cnt = [], 0
        def sumCoord(i, j):
            total = 0
            while i > 0:
                total += i % 10
                i = i // 10
            while j > 0:
                total += j % 10
                j = j // 10
            return total

        if k >= 0:
            q.append([0,0])
            grid[0][0] = 1 # Mark as visited
            cnt += 1

        while q:
            [x,y] = q.pop(0)
            if x+1 < m and grid[x+1][y] == 0 and sumCoord(x+1, y) <= k:
                q.append([x+1,y])
                grid[x+1][y] = 1
                cnt += 1

            if y+1 < n and grid[x][y+1] == 0 and sumCoord(x, y+1) <= k:
                q.append([x,y+1])
                grid[x][y+1] = 1
                cnt += 1
    
        return cnt

Solution 2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution: # DFS
    def movingCount(self, m: int, n: int, k: int) -> int:
        grid = [[0] * n for _ in range(m)]
        def sumCoord(i, j):
            total = 0
            while i > 0:
                total += i % 10
                i = i // 10
            while j > 0:
                total += j % 10
                j = j // 10
            return total

        def dfs(x, y):
            if x < 0 or x >= m or y < 0 or y >= n or grid[x][y] == 1 or sumCoord(x, y) > k:
                return 0
            
            grid[x][y] = 1 # Mark as visited
            return 1 + dfs(x + 1, y) + dfs(x, y + 1)

        return dfs(0, 0)

Explanation

  • This question is similar to the Leetcode 200, Number of Islands. Because of the properties of position indexes, we only need to check the right and down directions instead of all directions.
  • Solution 1 & 2
    • Time Complexity: O(M * N)
    • Space Complexity: O(M * N)

Task 2 - Q12. 矩阵中的路径

Question

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution: # DFS
    def exist(self, board: List[List[str]], word: str) -> bool:
        def dfs(x, y, id):
            if x < 0 or y < 0 or x >= len(board) or y >= len(board[0]) or board[x][y] != word[id]:
                return False
            elif id == len(word)-1: # Tracking which character is being tracked
                return True
            else:
                board[x][y] = "" # Mark as visited so that same elements won't be used multiple times
                res = dfs(x-1, y, id+1) or dfs(x, y-1, id+1) or dfs(x+1, y, id+1) or dfs(x, y+1, id+1)
                board[x][y] = word[id] # Put the original value back
                return res

        m, n = len(board), len(board[0])
        for i in range(0, m):
            for j in range(0, n):
                if dfs(i, j, 0):
                    return True

        return False

Explanation

  • Time Complexity: O(3K * M * N)
    • The length of the string is K and there are 4-1 options each time. The time would be O(3K)
    • There are M * N grids in total
  • Space Complexity: O(K)
    • The depth of recursion is no longer than K. In the worst case, K = MN.

MIT License
Last updated on Apr 25, 2022 08:52 EDT
Built with Hugo
Theme Stack designed by Jimmy