我在编码面试中遇到了这个问题。
您处于无限的2D网格中,您可以在8个方向中的任何一个方向移动:
(x,y)to (x + 1,y), (x - 1,y), (x,y + 1), (x,y-1), (x-1,y-1), (X + 1,Y + 1), (X-1,Y + 1), (X + 1,Y-1) 您将获得一系列需要涵盖的要点。给出可以实现它的最小步骤数。你从第一点开始。
示例:
输入:[(0,0),(1,1),(1,2)] 输出:2 从(0,0)移动到(1,1)需要1步。从(1,1)转移到(1,2)还需要一步。
我能够提出一个带有memoization(DP)技术的递归解决方案,同时保留访问点的列表,但仍然看起来并不完美。即使在面试之后,我仍然在考虑更好的解决方案。任何人都可以提出比我更好的解决方案吗?我需要帮助!
# @param X : list of integers
# @param Y : list of integers
# Points are represented by (X[i], Y[i])
# @return an integer
def coverPoints(self, X, Y):
if len(X) == 1:return 0
def odist(A, B): #to calculate shortest distance between a pair of points
min_d = 0 if abs(A[1]-B[1]) > abs(A[0]-B[0]) else 1
return abs(A[min_d]-B[min_d]) + (abs(A[1-min_d]-B[1-min_d])- abs(A[min_d]-B[min_d]))
D = {}
def rec(curL, last, dist):
if D.get((tuple(curL), dist), False) != False:return D[(tuple(curL),dist)]
if len(curL) == 0:return dist
else:
s = sys.maxsize
for id, i in enumerate(curL):
newL = curL[:id] + curL[id+1:]
s = min(s, rec(newL, id, odist( (X[last], Y[last]), (X[curL[id]], Y[curL[id]]) )))
D[(tuple(curL),dist)] = dist + s
return dist + s
s = rec([i for i in range(len(X))], 0, 0)
return s