并查集模板 typescript 130. 被围绕的区域

81 阅读1分钟

把四边的 O 联通到一个特殊父节点上,本代码是 empthNodeParent,这样再去数据的里面遍历,如果是 O 就联通,那么四边的O就联通在 empthNodeParent 上,符合条件的里面的O就联通在他们自己的一个节点上,最后遍历整个数组里面的O,如果不和empthNodeParent联通,那么他就应该变成X

// TypeScript 并查集实现

class UnionFind{
    // 可直接 实例.count 获取
    count: number
    parent: number[]

    constructor(n:number){
        this.count=n
        this.parent=Array.from({length:n},(a,b)=>b)
    }

    find(x:number):number{
        if(this.parent[x]!==x){
            this.parent[x]=this.find(this.parent[x])
        }
        return this.parent[x]
    }

    union(p:number,q:number){
        let rootP=this.find(p)
        let rootQ=this.find(q)
        if(rootP===rootQ){
            return
        }
        this.parent[rootQ]=rootP
    }

    connected(p:number,q:number){
        let rootP=this.find(p)
        let rootQ=this.find(q)
        return rootP === rootQ
    }

    getCount(){
        return this.count
    }
}

// 二维位置压缩到一维存储
function getId(x:number,y:number,n:number){
    return x*n+y
}

/**
 Do not return anything, modify board in-place instead.
 */
function solve(board: string[][]): void {
    let m=board.length
    let n=board[0].length
    let uf=new UnionFind(m*n+1)
    let empthNodeParent = m*n

    // 四个边的 O 要联通到 empthNodeParent 节点,代表特殊的 O
    for(let i=0;i<m;i++){
        if(board[i][0]==='O'){
            uf.union(getId(i,0,n),empthNodeParent)
        }
        if(board[i][n-1]==='O'){
            uf.union(getId(i,n-1,n),empthNodeParent)
        }
    }
    for(let i=0;i<n;i++){
        if(board[0][i]==='O'){
            uf.union(getId(0,i,n),empthNodeParent)
        }
        if(board[m-1][i]==='O'){
            uf.union(getId(m-1,i,n),empthNodeParent)
        }
    }

    let direction = [[-1,0],[0,1],[1,0],[0,-1]]

    for(let i=1;i<m-1;i++){
        for(let j=1;j<n-1;j++){
            if(board[i][j]==='O'){
                for(let k=0;k<direction.length;k++){
                    let tx=i+direction[k][0]
                    let ty=j+direction[k][1]
                    if(board[tx][ty]==='O'){
                        uf.union(getId(i,j,n),getId(tx,ty,n))
                    }
                }
            }
        }
    }
    for(let i=0;i<m;i++){
        for(let j=0;j<n;j++){
            if(board[i][j]==='O'&&!uf.connected(getId(i,j,n),empthNodeParent)){
                board[i][j]='X'
            }
        }
    }
};