• [Swift]LeetCode1030. 距离顺序排列矩阵单元格 | Matrix Cells in Distance Order


    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址: https://www.cnblogs.com/strengthen/p/10744606.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    We are given a matrix with R rows and C columns has cells with integer coordinates (r, c), where 0 <= r < R and 0 <= c < C.

    Additionally, we are given a cell in that matrix with coordinates (r0, c0).

    Return the coordinates of all cells in the matrix, sorted by their distance from (r0, c0) from smallest distance to largest distance.  Here, the distance between two cells (r1, c1) and (r2, c2) is the Manhattan distance, |r1 - r2| + |c1 - c2|.  (You may return the answer in any order that satisfies this condition.)

    Example 1:

    Input: R = 1, C = 2, r0 = 0, c0 = 0
    Output: [[0,0],[0,1]]
    Explanation: The distances from (r0, c0) to other cells are: [0,1]
    

    Example 2:

    Input: R = 2, C = 2, r0 = 0, c0 = 1
    Output: [[0,1],[0,0],[1,1],[1,0]]
    Explanation: The distances from (r0, c0) to other cells are: [0,1,1,2]
    The answer [[0,1],[1,1],[0,0],[1,0]] would also be accepted as correct.
    

    Example 3:

    Input: R = 2, C = 3, r0 = 1, c0 = 2
    Output: [[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]]
    Explanation: The distances from (r0, c0) to other cells are: [0,1,1,2,2,3]
    There are other answers that would also be accepted as correct, such as [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]].

    Note:

    1. 1 <= R <= 100
    2. 1 <= C <= 100
    3. 0 <= r0 < R
    4. 0 <= c0 < C

    给出 R 行 C 列的矩阵,其中的单元格的整数坐标为 (r, c),满足 0 <= r < R 且 0 <= c < C

    另外,我们在该矩阵中给出了一个坐标为 (r0, c0) 的单元格。

    返回矩阵中的所有单元格的坐标,并按到 (r0, c0) 的距离从最小到最大的顺序排,其中,两单元格(r1, c1) 和 (r2, c2) 之间的距离是曼哈顿距离,|r1 - r2| + |c1 - c2|。(你可以按任何满足此条件的顺序返回答案。)

    示例 1:

    输入:R = 1, C = 2, r0 = 0, c0 = 0
    输出:[[0,0],[0,1]]
    解释:从 (r0, c0) 到其他单元格的距离为:[0,1]
    

    示例 2:

    输入:R = 2, C = 2, r0 = 0, c0 = 1
    输出:[[0,1],[0,0],[1,1],[1,0]]
    解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2]
    [[0,1],[1,1],[0,0],[1,0]] 也会被视作正确答案。
    

    示例 3:

    输入: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. 1 <= R <= 100
    2. 1 <= C <= 100
    3. 0 <= r0 < R
    4. 0 <= c0 < C

    264ms
     1 lass Solution {
     2     
     3     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
     4         var distances = [Int: [[Int]]]()
     5         var q = Queue<(Int, Int)>()
     6         var visited = Set<Int>()
     7         q.push((r0 * C + c0, 0))
     8         visited.insert(r0 * C + c0)
     9         while !q.isEmpty {
    10             let (node, dist) = q.pop()
    11             let row = node / C
    12             let col = node % C
    13             distances[dist, default: []].append([row, col])
    14             if row > 0 && !visited.contains( (row - 1) * C + col ) {
    15                 q.push(((row - 1) * C + col, dist + 1))
    16                 visited.insert((row - 1) * C + col)
    17             }
    18             if row + 1 < R && !visited.contains( (row + 1) * C + col ) {
    19                 q.push(((row + 1) * C + col, dist + 1))
    20                 visited.insert((row + 1) * C + col)
    21             }
    22             
    23             if col > 0 && !visited.contains( row * C + col - 1) {
    24                 q.push((row * C + col - 1, dist + 1))
    25                 visited.insert(row * C + col - 1)
    26             }
    27             if col + 1 < C && !visited.contains( row * C + col + 1) {
    28                 q.push((row * C + col + 1, dist + 1))
    29                 visited.insert(row * C + col + 1)
    30             }
    31         }
    32         let keys = distances.keys.sorted()
    33         var res = [[Int]]()
    34         for key in keys {
    35             res += distances[key]!
    36         }
    37         return res
    38     }
    39 }
    40 
    41 struct Queue<T> {
    42     var arr: [T] = []
    43     var head = 0
    44     
    45     mutating func push(_ val: T) {
    46         arr.append(val)
    47     }
    48     
    49     mutating func pop() -> T {
    50         let res = arr[head]
    51         head += 1
    52         return res
    53     }
    54     
    55     var isEmpty: Bool {
    56         return head == arr.count
    57     }
    58 }

    300ms

     1 class Solution {
     2     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
     3         var res: [([Int], Int)] = []
     4         for r in (0..<R) {
     5             for c in (0..<C) {
     6                 res.append(([r,c],abs(r - r0)+abs(c - c0)))
     7             }
     8         }
     9          
    10         var tt = res.sorted{$0.1<$1.1}
    11         var rr: [[Int]] = []
    12         for r in tt {
    13             rr.append(r.0)
    14         }
    15         
    16         return rr
    17     }
    18 }

    316ms

     1 class Solution {
     2     
     3     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
     4         if R == 0 || C == 0{
     5             return [[Int]]()
     6         }
     7         
     8         var ar = [[Int]]()
     9         
    10         for r in 0..<R{
    11             for c in 0..<C{
    12                 var left = abs(r0 - r)
    13                 var right = abs(c0 - c)
    14                 var sum = left + right
    15                 ar.append([sum, r, c])
    16             }
    17         }
    18         var res = [[Int]]()
    19         ar = ar.sorted{$0[0] < $1[0]}
    20         for i in ar{
    21             res.append(Array(i[1...2]))
    22         }
    23         return res
    24     }
    25 }

    320ms

     1 class Solution {
     2     struct Node {
     3         var distance: Int
     4         var coordinate: [Int]
     5         init(_ distance: Int, _ coordinate: [Int]) {
     6             self.distance = distance
     7             self.coordinate = coordinate
     8         }
     9     }
    10     
    11     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
    12         
    13         var nodes = [Node]()
    14         for i in 0..<R {
    15             for j in 0..<C {
    16                 let distance = abs(r0-i) + abs(c0-j)
    17                 nodes.append(Node(distance, [i, j]))
    18             }
    19         }
    20         
    21         nodes.sort(by: { $0.distance <= $1.distance})
    22         return nodes.map { $0.coordinate }
    23     }
    24 }

    364ms

     1 class Solution {
     2     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
     3         let maxRDist = max(R - r0, r0 - 0)
     4         let maxCDist = max(C - c0, c0 - 0)
     5         let maxDist = maxRDist + maxCDist
     6         var dist = 0
     7         var allCoors = [[Int]]()
     8         var set = Set<[Int]>()
     9         set.insert([r0, c0])
    10         allCoors += Array(set)
    11 
    12         while dist < maxDist {
    13             var s = Set<[Int]>()
    14 //            print("====================(set)")
    15             for coor in set {
    16                 s.formUnion(coors(R, C, r0, c0, coor[0], coor[1], dist))
    17             }
    18 //            print("==========>>>>>>>>>>>>(s)")
    19             allCoors += Array(s)
    20             set = s
    21             dist += 1
    22         }
    23         return allCoors
    24     }
    25 
    26     func coors(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int, _ r: Int, _ c: Int, _ dist: Int) -> Set<[Int]> {
    27         let vr = r - r0
    28         let vc = c - c0
    29         let dr = vr != 0 ? vr / abs(vr) : 0
    30         let dc = vc != 0 ? vc / abs(vc) : 0
    31         var set = Set<[Int]>()
    32         var newRs: [Int] = []
    33         var newCs: [Int] = []
    34         if dr == 0 {
    35             if r + 1 < R, abs(r + 1 - r0) > abs(vr) {
    36                 newRs.append(r + 1)
    37             }
    38             if r - 1 >= 0, abs(r - 1 - r0) > abs(vr) {
    39                 newRs.append(r - 1)
    40             }
    41         } else if r + dr < R, r + dr >= 0 {
    42             newRs.append(r + dr)
    43         }
    44         for newR in newRs {
    45             set.insert([newR, c])
    46         }
    47         if dc == 0 {
    48             if c + 1 < C, abs(c + 1 - c0) > abs(vc) {
    49                 newCs.append(c + 1)
    50             }
    51             if c - 1 >= 0, abs(c - 1 - c0) > abs(vc) {
    52                 newCs.append(c - 1)
    53             }
    54         } else if c + dc < C, c + dc >= 0 {
    55             newCs.append(c + dc)
    56         }
    57         for newC in newCs {
    58             set.insert([r, newC])
    59         }
    60         return set
    61     }
    62 }

    384ms

     1 class Solution {
     2     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
     3         var distances: [[Int]] = Array(repeating: Array(repeating: 0, count: C), count: R)
     4         var result: [[Int]] = []
     5         for r in 0...(R - 1) {
     6             for c in 0...(C - 1) {
     7                 let distance = (c - c0).magnitude + (r - r0).magnitude
     8                 distances[r][c] = Int(distance)
     9                 result.append([r,c])
    10             }
    11         }
    12         
    13         return result.sorted { distances[$0[0]][$0[1]] < distances[$1[0]][$1[1]] }
    14     }
    15 }

    400ms

     1 class Solution {
     2     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
     3         var result = [[Int]]()
     4         
     5         for i in 0..<R {
     6             for j in 0..<C {
     7                 result.append([i,j])
     8             }
     9         }
    10         
    11         return result.sorted { distance($0[0], $0[1], r0, c0) < distance($1[0], $1[1], r0, c0 )}
    12     }
    13     
    14     private func distance(_ R1: Int, _ C1: Int, _ R0: Int, _ C0: Int) -> Int {
    15         return abs(R0-R1) + abs(C0-C1)
    16     }
    17 }

    Runtime: 480 ms

    Memory Usage: 20.5 MB
      1 class Solution {
      2     func allCellsDistOrder(_ R: Int, _ C: Int, _ r0: Int, _ c0: Int) -> [[Int]] {
      3         //优先队列
      4         var q = Heap<(Int,[Int])>.init { (f, s) -> Bool in
      5             return f.0 < s.0
      6         }
      7 
      8         for i in 0..<R
      9         {
     10             for j in 0..<C
     11             {
     12                 q.insert((getManhattan([r0,c0],[i,j]),[i,j]))
     13             }
     14         }
     15         var res:[[Int]] = [[Int]]()
     16         while(!q.isEmpty)
     17         {
     18             res.append(q.remove()!.1)
     19         }
     20         return res     
     21     }
     22     
     23     func getManhattan(_ p1:[Int],_ p2:[Int]) -> Int
     24     {
     25         return Int(abs(Double(p1[0] - p2[0])) + abs(Double(p1[1] - p2[1])))
     26     }
     27 }
     28 
     29 public struct Heap<T> {
     30     public var nodes = [T]()
     31     private var orderCriteria: (T, T) -> Bool
     32     
     33     public init(sort: @escaping (T, T) -> Bool) {
     34         orderCriteria = sort
     35     }
     36     
     37     public init(array: [T], sort: @escaping (T, T) -> Bool) {
     38         self.orderCriteria = sort
     39         configureHeap(from: array)
     40     }
     41     
     42     public var isEmpty: Bool {
     43         return nodes.isEmpty
     44     }
     45     
     46     public var count: Int {
     47         return nodes.count
     48     }
     49     
     50     public mutating func configureHeap(from array: [T]) {
     51         nodes = array
     52         for i in stride(from: nodes.count / 2 - 1, through: 0, by: -1) {
     53             shiftDown(i)
     54         }
     55     }
     56     
     57     public mutating func reset() {
     58         for i in stride(from: nodes.count / 2 - 1, through: 0, by: -1) {
     59             shiftDown(i)
     60         }
     61     }
     62     
     63     @inline(__always) internal func parentIndex(ofIndex index: Int) -> Int {
     64         return (index - 1) / 2
     65     }
     66     
     67     @inline(__always) internal func leftChildIndex(ofIndex index: Int) -> Int {
     68         return index * 2 + 1
     69     }
     70     
     71     @inline(__always) internal func rightChildIndex(ofIndex index: Int) -> Int {
     72         return index * 2 + 2
     73     }
     74     
     75     public func peek() -> T? {
     76         return nodes.first
     77     }
     78     
     79     internal mutating func shiftUp(_ index: Int) {
     80         var childIndex = index
     81         let child = nodes[childIndex]
     82         var parentIndex = self.parentIndex(ofIndex: index)
     83         while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
     84             nodes[childIndex] = nodes[parentIndex]
     85             childIndex = parentIndex
     86             parentIndex = self.parentIndex(ofIndex: childIndex)
     87         }
     88         nodes[childIndex] = child
     89     }
     90     
     91     internal mutating func shiftDown(from index: Int, until endIndex: Int) {
     92         let leftChildIndex = self.leftChildIndex(ofIndex: index)
     93         let rightChildIndex = self.rightChildIndex(ofIndex: index)
     94         
     95         var first = index
     96         if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
     97             first = leftChildIndex
     98         }
     99         if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
    100             first = rightChildIndex
    101         }
    102         if first == index {
    103             return
    104         }
    105         nodes.swapAt(index, first)
    106         shiftDown(from: first, until: endIndex)
    107     }
    108     
    109     internal mutating func shiftDown(_ index: Int) {
    110         shiftDown(from: index, until: nodes.count)
    111     }
    112     
    113     public mutating func insert(_ value: T) {
    114         nodes.append(value)
    115         shiftUp(nodes.count - 1)
    116     }
    117     
    118     public mutating func insert<S: Sequence>(_ sequence:S) where S.Iterator.Element == T {
    119         for value in sequence {
    120             insert(value)
    121         }
    122     }
    123     
    124     public mutating func replace(index i: Int, value: T) {
    125         guard i < nodes.count else {
    126             return
    127         }
    128         remove(at: i)
    129         insert(value)
    130     }
    131     
    132     @discardableResult
    133     public mutating func remove() -> T? {
    134         guard !nodes.isEmpty else {
    135             return nil
    136         }
    137         if nodes.count == 1 {
    138             return nodes.removeLast()
    139         } else {
    140             let value = nodes[0]
    141             nodes[0] = nodes.removeLast()
    142             shiftDown(0)
    143             return value
    144         }
    145     }
    146     
    147     @discardableResult
    148     public mutating func remove(at index: Int) -> T? {
    149         guard index < nodes.count else { return nil}
    150         let size = nodes.count - 1
    151         if index != size {
    152             nodes.swapAt(index, size)
    153             shiftDown(from: index,  until: size)
    154             shiftUp(index)
    155         }
    156         return nodes.removeLast()
    157     }
    158     
    159     public mutating func sort() -> [T] {
    160         for i in stride(from: self.nodes.count - 1, to: 0, by: -1) {
    161             nodes.swapAt(0, i)
    162             shiftDown(from: 0, until: i)
    163         }
    164         return nodes
    165     }    
    166 }
  • 相关阅读:
    python学习笔记(4)装饰器
    python学习笔记(3)函数
    python学习笔记(2)集合
    python学习笔记(1)字典
    nginx.conf文件内容详解
    关于斐波拉契数列引出的迭代器生成器的一点讨论
    MAC电脑运行python并发编程遇到的问题
    docker 11 :私有仓库搭建
    docker 10 :docker单机网络模式
    【转】C#环形队列
  • 原文地址:https://www.cnblogs.com/strengthen/p/10744606.html
Copyright © 2020-2023  润新知