壮志,敢教日月换新天。为有牺牲多

[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 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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 }
复制代码

 

posted @   为敢技术  阅读(406)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· SQL Server统计信息更新会被阻塞或引起会话阻塞吗?
阅读排行:
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 本地部署 DeepSeek:小白也能轻松搞定!
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 普通人也能轻松掌握的20个DeepSeek高频提示词(2025版)
点击右上角即可分享
微信分享提示