leetcode 1030 距离顺序排列矩阵单元格 桶排序+BFS 两种做法

思路:首先,很容易想到直接排序。但是排序复杂度那么高,排序是不可能排序的。这一看O(N)就能解决。简便的方法是用桶排序,由于是曼哈顿距离,比较好枚举。如果是几何距离的话,放到字典中还需要给字典的键排序,复杂度可能又要到O(NlogN)了。

解法一:桶排序
正规的桶排序是记录每个节点的位置,在以位置为下标的数组中记录。咱们的原理是一样的,只是可能每个桶有多个点。判断下最大距离,超出字典范围终止掉就好。

class Solution:
    def allCellsDistOrder(self, R: int, C: int, r0: int, c0: int) -> List[List[int]]:
        def get_dis(p1, p2):
            return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])

        d = {}
        for r in range(R):
            for c in range(C):
                dis = get_dis((r,c), (r0, c0))
                if dis in d:
                    d[dis].append([r, c])
                else:
                    d[dis] = [[r, c]]
        print(d)
        l = []
        max_dis = R+C-2
        for i in range(max_dis+1):
            if i not in d:
                break
            l.extend(d[i])
        
        return l

解法二:BFS
这题一开始拿到手是想着bfs的,但实在不知道咋弄,但一看这个图就懂了,直接BFS就行,这就是曼哈顿距离的魅力。

曼哈顿距离分布图

from queue import Queue
class Solution:
    def allCellsDistOrder(self, R: int, C: int, r0: int, c0: int) -> List[List[int]]:
        def out_of_range(r, c):
            if r < 0 or r >= R or c < 0 or c >= C:
                return 1
            return 0
        
        def bfs(r, c, l, traversed):
            q = Queue()
            q.put((r,c))
            traversed[r][c] = 1
            while not q.empty():
                (r, c) = q.get()
                if not out_of_range(r+1, c) and not traversed[r+1][c]:
                    q.put((r+1, c))
                    traversed[r+1][c] = 1
                if not out_of_range(r-1, c) and not traversed[r-1][c]: 
                    q.put((r-1, c)) 
                    traversed[r-1][c] = 1
                if not out_of_range(r, c+1) and not traversed[r][c+1]: 
                    q.put((r, c+1)) 
                    traversed[r][c+1] = 1
                if not out_of_range(r, c-1) and not traversed[r][c-1]: 
                    q.put((r, c-1)) 
                    traversed[r][c-1] = 1
                l.append([r, c])

        l, traversed = [], [[0 for _ in range(C)] for _ in range(R)]
        bfs(r0, c0, l, traversed)
        return l

注意,可以用一个二维数组代替字典存遍历过的路径

解法三:找规律(几何法)
建模较困难,跟BFS一样的原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值