Interview Question 13-The Range of Motion of the Robot

Interview Question 13-The Range of Motion of the Robot

Title description

There is a grid with m rows and n columns on the ground, from coordinate [0,0] to coordinate [m-1, n-1]. A robot starts from the grid of coordinates [0, 0], it can move one grid to the left, right, up, and down at a time (it cannot move outside the grid), nor can it enter the row and column coordinates. k's lattice. For example, when k is 18, the robot can enter the square [35, 37] because 3 + 5 + 3 + 7 = 18. But it cannot enter the square [35, 38] because 3 + 5 + 3 + 8 = 19. How many grids can the robot reach?

示例 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

This subject is 79-WordSearchmuch simpler than that. The subject requirements areThe total number of grids that meet the requirements, so each grid can walk multiple times. For this question, BFS is more suitable than DFS. In this way we can draw an intuitive solution to the problem:

Starting from the origin (0,0), as long as the sum is less than K, it is marked as True. Finally, it is only necessary to traverse the entire mxn matrix and calculate all Truethe numbers.

79-WordSearchIt is a problem of finding the path, so not only need to mark the status, but also need to backtrack, and then reset the status.

solution

class Solution:
	directions = [(0,-1),(-1,0),(0,1),(1,0)]
	def movingCount(self, m: int, n: int, k: int) -> int:
		marked = [[False  for _ in  range(n)] for _ in  range(m)]
		self.__move(0, 0, marked, m, n, k)
		result = 0
		for i in  range(m):
			for j in  range(n):
				if marked[i][j] == True:
					result += 1
		return result

	def __move(self,start_x, start_y, marked, m, n, k):
		str_start = str(start_x) + str(start_y)
		sum_start = 0
		for i in  range(len(str_start)):
			sum_start += int(str_start[i])
		if sum_start <= k:
			marked[start_x][start_y] = True
			# examine next point
			for direction in  self.directions:
				new_x = start_x + direction[0]
				new_y = start_y + direction[1]
				if  0<= new_x <m and  0<= new_y <n and \
					not marked[new_x][new_y]:
					self.__move(new_x, new_y, marked, m, n, k)

When the current node (start_x, start_y)meets the requirements, based on it, it traverses whether the neighboring nodes in the four directions around meet the requirements; if the points that meet the requirements are found, continue to check the neighboring nodes. This is the iteration

optimization

How to calculate the sum of digits of a number?

We only need to take the remainder of 10 for log x to know the number of digits in x; then divide x by 10. This operation is equivalent to shifting the decimal number of x to the right by 1 The number of digits (similar to the >> right shift operator in binary), repeating until x ends at 0.

Hidden optimization

During our search, the search direction can be reduced to right and down , instead of searching up and left. In this answer , the map of 16 * 16 is shown. With the enlargement of the restriction condition k, the change trend of feasible squares. The value in each square is the sum of the digits of the row and column coordinates. Obstacle grid, that is, its value is less than or equal to the current limit condition k.
We can find that as the restriction k increases, the newly added non-obstructed squares in the blue square area where (0, 0) is located can be obtained by moving the upper or left square one step.
The other unconnected blue grid areas will be connected with the increase of k, and the connection is also obtained by moving the upper or left grid one step, so we can reduce our search direction to right or under.

The reference code given below is used queue, which is the queue. There are major queue.put()and queue.get()methods. The solution is:
set up a set to ssave the nodes that meet the requirements; set up a queue to save the nodes to be judged. Finally, by calculating sthe number in the set , the number that meets the requirements is obtained.

Generally speaking, the BFS search problem will be solved by the method of queue.

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))
                for nx, ny in [(x + 1, y), (x, y + 1)]:
                    q.put((nx, ny))
        return len(s)

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/ji-qi-ren-de-yun-dong-fan-wei-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

This method is less efficient than its own method . Of course, the above two optimization methods are still great for optimizing your own code.

Recursive method

Considering that the search direction only needs to be down or right, we can derive a recursive solution method.

Defined vis[i][j]as (i, j)whether the coordinate is reachable, if it is reachable, it returns 1, otherwise it returns 0.

First, (i, j) needs to be accessible, so it is necessary to determine whether the sum of the digits of i and j is greater than k, and if it is greater, directly set it vis[i][j]as unreachable.

Otherwise, the search direction mentioned above only needs to be down or right, so the grid of (i, j) will only come from the two grids of (i-1, j) or (i, j-1) (regardless of the boundary Condition) , then the vis[i][j]reachability state can be calculated by the following formula:

\ (\ textit {vis} [i] [j] = \ textit {vis} [i-1] [j] \ \ textrm {or} \ \ textit {vis} [i] [j-1] \)

That is, as long as one grid is reachable, then (i, j) this grid is reachable , so we only need to traverse all the grids, recursively calculate whether they are reachable, and then use the variable ans to record the number of reachable grids.

Initial conditions vis[i][j] = 1, pay attention to the handling of boundaries during the recursive calculation.

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:
        vis = set([(0, 0)])
        for i in range(m):
            for j in range(n):
                if ((i - 1, j) in vis or (i, j - 1) in vis) and \
	                digitsum(i) + digitsum(j) <= k:
                    vis.add((i, j))
        return len(vis)

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/ji-qi-ren-de-yun-dong-fan-wei-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

The efficiency of this method is similar to that of your own code.

Guess you like

Origin www.cnblogs.com/rongyupan/p/12681754.html