• [Swift]LeetCode947. 移除最多的同行或同列石头 | Most Stones Removed with Same Row or Column


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

    On a 2D plane, we place stones at some integer coordinate points.  Each coordinate point may have at most one stone.

    Now, a move consists of removing a stone that shares a column or row with another stone on the grid.

    What is the largest possible number of moves we can make?

    Example 1:

    Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
    Output: 5
    

    Example 2:

    Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
    Output: 3
    

    Example 3:

    Input: stones = [[0,0]]
    Output: 0

    Note:

    1. 1 <= stones.length <= 1000
    2. 0 <= stones[i][j] < 10000

    在二维平面上,我们将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。

    现在,move 操作将会移除与网格上的另一块石头共享一列或一行的石头。

    我们最多能执行多少次 move 操作?

    示例 1:

    输入:stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
    输出:5
    

    示例 2:

    输入:stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
    输出:3
    

    示例 3:

    输入:stones = [[0,0]]
    输出:0

    提示:

    1. 1 <= stones.length <= 1000
    2. 0 <= stones[i][j] < 10000

    272ms

      1 class Solution {
      2         class Coordinate:Hashable{
      3             static func == (lhs: Coordinate, rhs: Coordinate) -> Bool {
      4                 return lhs.x == rhs.x && lhs.y == rhs.y;
      5             }
      6             
      7             let x:Int;
      8             let y:Int;
      9             init(x:Int,y:Int) {
     10                 self.x = x;
     11                 self.y = y;
     12             }
     13             var hashValue:Int{
     14                 return x.hashValue ^ y.hashValue;
     15             }
     16         }
     17         class Vertex:Hashable,Comparable{
     18             var hashValue:Int{
     19                 get{
     20                     return co.hashValue;
     21                 }
     22             }
     23             static func < (lhs: Vertex, rhs: Vertex) -> Bool {
     24                 return lhs.degree < rhs.degree;
     25             }
     26             
     27             static func == (lhs: Vertex, rhs: Vertex) -> Bool {
     28                 return lhs.co == rhs.co;
     29             }
     30             let co:Coordinate;
     31             var neighbors:Set<Vertex>;
     32             var degree:Int{
     33                 get {
     34                     return neighbors.count;
     35                 }
     36             }
     37             var traversed:Bool;
     38             init(x:Int,y:Int) {
     39                 self.co = Coordinate(x: x, y: y);
     40                 neighbors = Set<Vertex>();
     41                 traversed = false;
     42             }
     43         }
     44         var max = 0;
     45         func removeStones(_ stones: [[Int]]) -> Int {
     46             max = 0;
     47             if stones.count < 2{
     48                 return 0;
     49             }
     50             var allStones = Dictionary<Coordinate,Vertex>();
     51             var xDict = Dictionary<Int,Array<Coordinate>>();
     52             var yDict = Dictionary<Int,Array<Coordinate>>();
     53             for stone in stones{
     54                 let x = stone[0];
     55                 let y = stone[1];
     56                 let co = Coordinate(x: x, y: y);
     57                 let vertex = Vertex(x: x, y: y);
     58                 allStones[co] = vertex;
     59                 if xDict[x] == nil{
     60                     xDict[x] = Array<Coordinate>()
     61                 }
     62                 if yDict[y] == nil{
     63                     yDict[y] = Array<Coordinate>()
     64                 }
     65                 xDict[x]!.append(co);
     66                 yDict[y]!.append(co);
     67             }
     68             
     69             for coco in allStones.keys{
     70                 let v = allStones[coco]!;
     71                 let x = coco.x;
     72                 let y = coco.y;
     73 //                let keys = allStones.keys;
     74                 var leftClosest:Coordinate?
     75                 var rightClosest:Coordinate?
     76                 var topClosest:Coordinate?
     77                 var bottomClosest:Coordinate?
     78                 for c in xDict[x]!{
     79                     if c.y != y{
     80                         if c.y < y{
     81                             if topClosest == nil || topClosest!.y < c.y{
     82                                 topClosest = c;
     83                             }
     84                         }else{
     85                             if bottomClosest == nil || bottomClosest!.y > c.y{
     86                                 bottomClosest = c;
     87                             }
     88                         }
     89                     }
     90                 }
     91                 for c in yDict[y]!{
     92                     if c.x != x{
     93                         if c.x < x{
     94                             if leftClosest == nil || leftClosest!.x < c.x{
     95                                 leftClosest = c;
     96                             }
     97                         }else{
     98                             if rightClosest == nil || rightClosest!.y > c.y{
     99                                 rightClosest = c;
    100                             }
    101                         }
    102                     }
    103                 }
    104                 if leftClosest != nil{
    105                     v.neighbors.insert(allStones[leftClosest!]!)
    106                 }
    107                 if rightClosest != nil{
    108                     v.neighbors.insert(allStones[rightClosest!]!)
    109                 }
    110                 if topClosest != nil{
    111                     v.neighbors.insert(allStones[topClosest!]!)
    112                 }
    113                 if bottomClosest != nil{
    114                     v.neighbors.insert(allStones[bottomClosest!]!)
    115                 }
    116             }
    117             for v in allStones.values{
    118                 let n = dfs(vertex: v) - 1;
    119                 if n > 0{
    120                     max += n;
    121                 }
    122             }
    123             return max;
    124         }
    125         func dfs(vertex:Vertex) -> Int {
    126             if vertex.traversed{
    127                 return 0;
    128             }else{
    129                 var sum = 1;
    130                 vertex.traversed = true;
    131                 for v in vertex.neighbors{
    132                     sum += dfs(vertex: v);
    133                 }
    134                 return sum;
    135             }
    136         }
    137     }

    316ms

     1 class Solution {
     2     func removeStones(_ stones: [[Int]]) -> Int {
     3         guard stones.count > 0 else {
     4             return 0
     5         }
     6         var v = [Int](repeating: 0, count: stones.count)
     7         var dr = [Int: [Int]]()
     8         var dc = [Int: [Int]]()
     9         for i in 0 ..< stones.count {
    10             let s = stones[i]
    11             dr[s[1], default: [Int]()].append(i)
    12             dc[s[0], default: [Int]()].append(i)
    13         }
    14         func bfs(_ i: Int) {
    15             var qs = [stones[i]]
    16             while !qs.isEmpty {
    17                 //print(v)
    18                 let u = qs.remove(at: 0)
    19                 let rs = dr[u[1], default: [Int]()]
    20                 let cs = dc[u[0], default: [Int]()]
    21                 var d = [Int: Bool]()
    22                 let ns = rs + cs
    23                 for n in ns {
    24                     d[n] = true
    25                 }
    26                 let ks = Array(d.keys)
    27                 for k in ks {
    28                     if v[k] != 2 {
    29                         v[k] += 1
    30                     }
    31                 }
    32                 qs += ks.filter {v[$0] == 1}.map {stones[$0]}
    33             }
    34         }
    35         var res = 0
    36         for i in 0 ..< stones.count {
    37             guard v[i] != 2 else {
    38                 continue
    39             }
    40             res += 1
    41             bfs(i)
    42         }
    43         return stones.count - res
    44 
    45     }
    46 }

    1284ms

     1 class Solution {
     2     func removeStones(_ stones: [[Int]]) -> Int {        
     3         
     4         let unionFind = UnionFind(stones.count)
     5         for i in 0..<stones.count-1 {
     6             for j in i+1..<stones.count {
     7                 if stones[i][0] == stones[j][0] || 
     8                    stones[i][1] == stones[j][1] {
     9                     unionFind.union(i, j)
    10                 }
    11             }
    12         }
    13         
    14         var counter = 0
    15         for i in 0..<unionFind.root.count {
    16             if unionFind.root[i] != i {
    17                 counter += 1
    18             }
    19         }
    20         return counter
    21     }
    22 }
    23 
    24 class UnionFind {
    25     var root = [Int]()
    26     var rank = [Int]()
    27     
    28     public init(_ n: Int) {
    29          // if root is not initialized, 'self' captured by a closure before all members were initialized
    30         (0...n-1).forEach { root.append($0) }
    31         rank = [Int](repeating: 1, count: n)
    32     }
    33         
    34     fileprivate func find(_ current: Int) -> Int {
    35         var path = [Int]()
    36         var current = current
    37         while root[current] != current {
    38             path.append(current)
    39             current = root[current]
    40         }
    41         
    42         for p in path {
    43             root[p] = current
    44         }
    45         return current
    46     }
    47     
    48     public func union(_ x: Int, _ y: Int) {
    49         let xRoot = find(x)
    50         let yRoot = find(y)
    51         
    52         if xRoot == yRoot {
    53             return
    54         }
    55         if rank[xRoot] > rank[yRoot] {
    56             root[yRoot] = xRoot
    57         } else if rank[xRoot] < rank[yRoot] {
    58             root[xRoot] = yRoot
    59         } else {
    60             rank[xRoot] = root[xRoot] + 1
    61             root[xRoot] = yRoot
    62         }
    63     }
    64 }

    1436ms

     1 class Solution {
     2     func removeStones(_ stones: [[Int]]) -> Int {
     3         var n:Int = stones.count
     4         var ds:DJSet = DJSet(n)
     5         for i in 0..<n
     6         {
     7             for j in (i + 1)..<n
     8             {
     9                 if stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1]
    10                 {
    11                     ds.union(i, j)
    12                 }
    13             }
    14         }
    15         return n-ds.count()
    16     }
    17 }
    18 
    19 public class DJSet 
    20 {
    21     var upper:[Int] = [Int]()
    22     
    23     public init(_ n:Int)
    24     {
    25         upper = [Int](repeating:-1,count: n)
    26     }
    27     
    28     public func root(_ x:Int) -> Int
    29     {
    30         if upper[x] < 0
    31         {
    32             return x
    33         }
    34         else
    35         {
    36             upper[x] = root(upper[x])
    37             return upper[x]
    38         }
    39     }
    40     
    41     public func equiv(_ x:Int,_ y:Int) -> Bool
    42     {
    43         return root(x) == root(y)
    44     }
    45     
    46     public func union(_ x:Int,_ y:Int) -> Bool
    47     {
    48         var x:Int = root(x)
    49         var y:Int = root(y)
    50         if (x != y)
    51         {
    52             if (upper[y] < upper[x]) 
    53             {
    54                 var d:Int = x
    55                 x = y
    56                 y = d
    57             }
    58             upper[x] += upper[y]
    59             upper[y] = x
    60         }
    61         return x == y
    62     }
    63 
    64     public func count()-> Int 
    65     {
    66         var ct:Int = 0
    67         for u in upper
    68         {
    69             if u < 0
    70             {
    71                 ct += 1
    72             }
    73         }
    74         return ct
    75     }
    76 }

    1476ms
      1 class Solution {
      2     func removeStones(_ stones: [[Int]]) -> Int {
      3         
      4         var xPointsMap:[Int:[[Int]]] = [:]
      5         var yPointsMap:[Int:[[Int]]] = [:]
      6         var xTag:[Int:Int] = [:]
      7         var yTag:[Int:Int] = [:]
      8         
      9         // merge by x and y
     10         for stone in stones {
     11             
     12             let x = stone[0]
     13             let y = stone[1]
     14             if let _ = xPointsMap[x] {
     15                 xPointsMap[x]!.append(stone)
     16             } else {
     17                 xPointsMap[x] = [stone]
     18             }
     19             
     20             if let _ = yPointsMap[y] {
     21                 yPointsMap[y]!.append(stone)
     22             } else {
     23                 yPointsMap[y] = [stone]
     24             }
     25         }
     26         
     27         // init x tags and y tags
     28         for (x,_) in xPointsMap {
     29             xTag[x] = 0
     30         }
     31         for (y,_) in yPointsMap {
     32             yTag[y] = 0
     33         }
     34         
     35         var totalMove = 0
     36         
     37         var currentTag = 1
     38         while true {
     39             var startX:Int?
     40             for (x,tag) in xTag {
     41                 if tag == 0 {
     42                     startX = x
     43                 }
     44             }
     45             if let sx = startX {
     46                 var xSet:Set<Int> = [sx]
     47                 func yforxSet(_ xSet:Set<Int>) -> Set<Int> {
     48                     var ySet:Set<Int> = []
     49                     for x in xSet {
     50                         for point in xPointsMap[x] ?? [] {
     51                             let y = point[1]
     52                             if yTag[y] == 0 {
     53                                 ySet.insert(y)
     54                             }
     55                         }
     56                     }
     57                     return ySet
     58                 }
     59                 
     60                 func xforySet(_ ySet:Set<Int>) -> Set<Int> {
     61                     var xSet:Set<Int> = []
     62                     for y in ySet {
     63                         for point in yPointsMap[y] ?? [] {
     64                             let x = point[0]
     65                             if xTag[x] == 0 {
     66                                 xSet.insert(x)
     67                             }
     68                         }
     69                     }
     70                     return xSet
     71                 }
     72                 var ySet = yforxSet(xSet)
     73                 var deltaY:Set<Int> = ySet
     74                 
     75                 while true {
     76                     var thisX = xforySet(deltaY)
     77                     var deltaX = thisX.subtracting(xSet)
     78                     if (deltaX.count == 0) {
     79                         break;
     80                     }
     81                     xSet = xSet.union(deltaX)
     82                     var thisY = yforxSet(deltaX)
     83                     deltaY = thisY.subtracting(ySet)
     84                     ySet = ySet.union(deltaY)
     85                 }
     86                 
     87                 var pointsCount = 0
     88                 
     89                 for x in xSet {
     90                     xTag[x] = currentTag
     91                     pointsCount += xPointsMap[x]?.count ?? 0
     92                 }
     93                 for y in ySet {
     94                     yTag[y] = currentTag
     95                 }
     96                 
     97                 if (pointsCount >= 1) {
     98                     totalMove += pointsCount - 1
     99                 }
    100                 
    101                 currentTag += 1
    102             } else {
    103                 break
    104             }
    105             
    106         }
    107         return totalMove;
    108     }
    109 }

    1956ms

     1 class Solution {
     2     func removeStones(_ stones: [[Int]]) -> Int {
     3         var sets = [(Set<Int>, Set<Int>)]()
     4         for i in 0..<stones.count {
     5             let s = stones[i]
     6             let row = sets.index(where: { $0.0.contains(s[0]) })
     7             let col = sets.index(where: { $0.1.contains(s[1]) })
     8             if let col = col, let row = row, col != row {
     9                 let unionRows = sets[row].0.union(sets[col].0)
    10                 let unionCols = sets[row].1.union(sets[col].1)
    11                 if row < col {
    12                     sets.remove(at: col)
    13                     sets.remove(at: row)
    14                 }else {
    15                     sets.remove(at: row)
    16                     sets.remove(at: col)
    17                 }
    18                 sets.append((unionRows, unionCols))
    19             } else if let row = row {
    20                 sets[row].0.insert(s[0])
    21                 sets[row].1.insert(s[1])
    22             } else if let col = col {
    23                 sets[col].0.insert(s[0])
    24                 sets[col].1.insert(s[1])
    25             } else {
    26                 sets.append((Set([s[0]]), Set([s[1]])))
    27             }
    28         }
    29         return stones.count-sets.count
    30     }
    31 }

  • 相关阅读:
    Object Modeling
    数据库的比较
    关系数据库与非关系数据库
    结构化查询语言-SQL
    SQLite
    acid (数据库事务正确执行的四个基本要素的缩写)
    UITableView设计思想 考察
    复杂软件的考虑点与UITableView
    设计模式与哲学
    复杂对象的组装与创建-建造者模式
  • 原文地址:https://www.cnblogs.com/strengthen/p/10015292.html
Copyright © 2020-2023  润新知