思路1,暴力法,超时。
1 import sys 2 class Solution: 3 def maxDistance(self, grid: 'List[List[int]]') -> int: 4 row = len(grid) 5 column = len(grid[0]) 6 waters = [] 7 lands = [] 8 for i in range(row): 9 for j in range(column): 10 if grid[i][j] == 0: 11 waters.append([i,j]) 12 else: 13 lands.append([i,j]) 14 result = -1 15 for i in range(len(waters)): 16 curmin = sys.maxsize 17 for j in range(len(lands)): 18 cur = abs(waters[i][0]-lands[j][0]) + abs(waters[i][1]-lands[j][1]) 19 if cur < curmin: 20 curmin = cur 21 if curmin != sys.maxsize and curmin > result: 22 result = curmin 23 return result
思路2,DFS,超时:
1 import sys 2 class Solution: 3 def dfs(self,grid,row,column,i,j,visited,dirct,path,dp): 4 if i < 0 or i >= row or j < 0 or j >= column: 5 return -1 6 if visited[i][j] == 1: 7 return -1 8 if grid[i][j] == 1: 9 return path 10 if grid[i][j] == 0 and dp[i][j] > 0: 11 return path + dp[i][j] 12 visited[i][j] = 1 13 minval = sys.maxsize 14 for di in dirct: 15 x = i + di[0] 16 y = j + di[1] 17 res = self.dfs(grid,row,column,x,y,visited,dirct,path+1,dp) 18 if res != -1 and res < minval: 19 minval = res 20 21 visited[i][j] = 0 22 if minval != sys.maxsize: 23 return minval 24 else: 25 return -1 26 27 def maxDistance(self, grid: 'List[List[int]]') -> int: 28 row = len(grid) 29 column = len(grid[0]) 30 if row == 0 or column == 0: 31 return -1 32 maxdis = -1 33 visited = [[0 for _ in range(column)]for _ in range(row)] 34 dirct = [[-1,0],[0,1],[1,0],[0,-1]] 35 dp = [[0 for _ in range(column)]for _ in range(row)] 36 for i in range(row): 37 for j in range(column): 38 if grid[i][j] == 0: 39 dis = self.dfs(grid,row,column,i,j,visited,dirct,0,dp) 40 dp[i][j] = dis 41 if dis > 0 and maxdis < dis: 42 maxdis = dis 43 #print(dis) 44 #print(dp) 45 return maxdis
思路3,BFS,应该是正确的选择。
比赛的时候没做出来,搞了1个小时的DFS,之前遇到过一道非常类似的题目,也是使用DFS会TLE,使用BFS可以AC。
我就不做了,给一个参考答案吧:
1 class Solution { 2 public int maxDistance(int[][] grid) { 3 int m = grid.length, n = grid[0].length; 4 boolean[][] visited = new boolean[m][n]; 5 Queue<int[]> q = new LinkedList<>(); 6 for (int i = 0; i < m; i++) { 7 for (int j = 0; j < n; j++) { 8 if (grid[i][j] == 1) { 9 visited[i][j] = true; 10 q.offer(new int[]{i, j}); 11 } 12 } 13 } 14 int[][] dirs = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; 15 int result = -1; 16 while (!q.isEmpty()) { 17 int size = q.size(); 18 while (size-- > 0) { 19 int[] cur = q.poll(); 20 result = Math.max(result, grid[cur[0]][cur[1]] - 1); 21 for (int[] dir : dirs) { 22 int x = cur[0] + dir[0], y = cur[1] + dir[1]; 23 if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y]) { 24 visited[x][y] = true; 25 grid[x][y] = grid[cur[0]][cur[1]] + 1; 26 q.offer(new int[]{x, y}); 27 } 28 } 29 } 30 } 31 return result == 0 ? -1 : result; 32 } 33 }
根据我的实际情况,我已经尽可能给了自己充足的时间练习算法了,现在是对我的算法水平进行最终的评估的时候了。
以实际的数据来评分:
leetcode的周赛:90分钟,4道题一般能A出2道。
互联网校招笔试:120分钟,4道题一般能A出1道。
我问了问其他的同学,也差不多是这样。
最终评价:以“补短板,力求达到算法平均水平”为目标的算法练习——目标达成。
感谢自己这几个月的努力。