题目描述:
难度简单31给出 R 行 C 列的矩阵,其中的单元格的整数坐标为 (r, c),满足 0 <= r < R 且 0 <= c < C。
另外,我们在该矩阵中给出了一个坐标为 (r0, c0) 的单元格。
返回矩阵中的所有单元格的坐标,并按到 (r0, c0) 的距离从最小到最大的顺序排,其中,两单元格(r1, c1) 和 (r2, c2) 之间的距离是曼哈顿距离,|r1 - r2| + |c1 - c2|。(你可以按任何满足此条件的顺序返回答案。)
示例:
输入:R = 2, C = 3, r0 = 1, c0 = 2
输出:[[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]]
解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2,2,3]
其他满足题目要求的答案也会被视为正确,例如 [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]]。
输出:[[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]]
解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2,2,3]
其他满足题目要求的答案也会被视为正确,例如 [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]]。
几种实现方式如下:
1 def celldistance(R, C, r0, c0): 2 ''' 3 桶排序思想 4 :param R: 5 :param C: 6 :param r0: 7 :param c0: 8 :return: 9 ''' 10 dis = [[] for i in range(100)] 11 for r in range(R): 12 for c in range(C): 13 # 计算距离 14 distance = abs((r - r0)) + abs((c - c0)) 15 dis[distance].append([r, c]) 16 17 print("dis=", dis) 18 result = [] 19 for i in dis: 20 if i: 21 result.extend(i) 22 23 return result 24 25 26 print("------------测试celldistance()------------") 27 result = celldistance(3, 4, 0, 0) 28 print('result=', result) 29 30 dis = [[]] * 10 31 dis1 = [[] for i in range(10)] 32 print("dis=", dis) 33 print("dis1=", dis1) 34 35 36 def celldistance1(R, C, r0, c0): 37 ''' 38 使用lambda表达式 39 :param R: 40 :param C: 41 :param r0: 42 :param c0: 43 :return: 44 ''' 45 # res = [] 46 # res = [[i, j] for i in range(R) for j in range(C)] 47 # print("res=", res) 48 49 res = sorted([[i, j] for i in range(R) for j in range(C)], 50 key=lambda item: abs(item[0] - r0) + abs(item[1] - c0)) 51 # for i in range(R): 52 # for j in range(C): 53 # res.append([i, j]) 54 55 # res.sort(key=lambda x: abs(x[0] - r0) + abs(x[1] - c0)) 56 57 return res 58 59 60 print("-----------测试celldistance1()-----------") 61 result = celldistance1(3, 4, 1, 1) 62 print("result=", result) 63 64 65 def celldistance2(R, C, r0, c0): 66 ''' 67 使用字典,距离作为键,位置坐标作为值 68 :param R: 69 :param C: 70 :param r0: 71 :param c0: 72 :return: 73 ''' 74 res = {} 75 for i in range(R): 76 for j in range(C): 77 distance = abs(i - r0) + abs(j - c0) 78 if distance not in res: 79 res[distance] = [] 80 res[distance].append([i, j]) 81 else: 82 res[distance].append([i, j]) 83 result = [] 84 for index in sorted(res.keys()): 85 result.extend(res[index]) 86 87 return result 88 89 90 print("============测试celldistance2()===========") 91 result = celldistance2(3, 4, 0, 0) 92 print("result=", result)
输出:
------------测试celldistance()------------ dis= [[[0, 0]], [[0, 1], [1, 0]], [[0, 2], [1, 1], [2, 0]], [[0, 3], [1, 2], [2, 1]], [[1, 3], [2, 2]], [[2, 3]], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []] result= [[0, 0], [0, 1], [1, 0], [0, 2], [1, 1], [2, 0], [0, 3], [1, 2], [2, 1], [1, 3], [2, 2], [2, 3]] dis= [[], [], [], [], [], [], [], [], [], []] dis1= [[], [], [], [], [], [], [], [], [], []] -----------测试celldistance1()----------- result= [[1, 1], [0, 1], [1, 0], [1, 2], [2, 1], [0, 0], [0, 2], [1, 3], [2, 0], [2, 2], [0, 3], [2, 3]] ============测试celldistance2()=========== result= [[0, 0], [0, 1], [1, 0], [0, 2], [1, 1], [2, 0], [0, 3], [1, 2], [2, 1], [1, 3], [2, 2], [2, 3]]
可以看到,在三种实现方式中,分别使用了桶排序思想,lambda表达式形式排序和字典存储,但归根结底,桶排序思想和字典存储具有相似之处,都是以距离为依据,将相同距离的值放入同一个容器中(桶排序中表现为存储在同一列表,字典表现为存储在同一键值下),因此只是两种不同的实现方式而已,是不是你也可以想到可以采用哈希表形式来实现(哈希表个人目前理解有点类似字典),感兴趣的可以尝试实现做一做。
另外,不是你是否发现,桶排序实现和字典存储在追加元素时,都要对某些元素初始化(桶排序中表现为列表索引要存在,所以在一开始将列表初始化为含有100个元素的空列表,字典中表现为键值必须存在),如果初始化给你带来一点不便的话,那么方法二中采用的lambda表达式形式,显然要简便的多,列表推导式存储所有矩阵位置,然后对列表元素按曼哈顿距离进行排序即可。