leetcode 交换字符串中的元素 && 腐烂的橘子

115 阅读1分钟

994. 腐烂的橘子

leetcode-cn.com/problems/ro…

  • bfs 腐烂的🍊向四周扩散
/**
 * @param {number[][]} grid
 * @return {number}
 */
var orangesRotting = function(grid) {
    const dirctions = [[1,0],[0,1],[-1,0],[0,-1]]
    const width = grid.length
    const height = grid[0].length
    let goodOrg = []
    let badOrg = []
    let badCounter = 0
    let time = -1
    for(let i=0;i<width;i++){
        for(let j=0;j<height;j++){
            if(grid[i][j] === 1){
                goodOrg.push([i,j])
            }else if(grid[i][j] ===2){
                badOrg.push([i,j])
            }
        }
    }
    if(!goodOrg.length){
        return 0
    }
    const sum = badOrg.length + goodOrg.length
    while(badOrg.length){
        time ++ 
        const size = badOrg.length
        for(let k=0;k<size;k++){
            const [x,y] = badOrg.shift()
            badCounter ++ 
            for(let dir =0;dir<dirctions.length;dir++){
                const nowX = x + dirctions[dir][0]
                const nowY = y + dirctions[dir][1]
                if(nowX>=0 && nowY >=0 && nowX < width && nowY <height && grid[nowX][nowY] === 1){
                    grid[nowX][nowY] =2
                    badOrg.push([nowX,nowY])
                }
            }
        }
    }
    if(badCounter === sum){
        return time
    }else{
        return -1
    }
};

1202. 交换字符串中的元素

leetcode-cn.com/problems/sm…

  • 步骤一:并查集将可交换的字符串分类
  • 步骤二:生成map对象存贮以可以互相交换的字符串的数组
  • 步骤三:对集合中的字符串排序
  • 步骤四:循环字符串并取出数组中最大的字符替换当前的字符 合并(Merge):把两个不相交的集合合并为一个集合。 查询(Find):查询两个元素是否在同一个集合中。
/**
 * @param {string} s
 * @param {number[][]} pairs
 * @return {string}
 */
var smallestStringWithSwaps = function(s, pairs) {
    if(pairs.length === 0 ) return s
    const djs = new DisJointSet(s.length)
    // 将可以交换的index合并
    for(const [x,y] of pairs){
        djs.merge(x,y)
    }
    const map = {}
    // 生成map对象存贮以可以互相交换的字符串的集合
    for(let i =0;i<s.length;i++){
        const p = djs.find(i)
        if(!map[p]){
            map[p] = []
        }
        map[p].push(s[i])
    }
    // 对集合中的字符串排序 从小到大排序
    for(const k in map){
        map[k].sort((a,b) => b.charCodeAt(0) - a.charCodeAt(0))
    }

    const res = new Array(s.length)
    // 找出当前字符串集合中的最大的放入对应的位置
    for(let i=0;i<s.length;i++){
        const p = djs.find(i)
        const strArr = map[p]
        res[i] = strArr.pop()
    }
    return res.join("")
};
class DisJointSet{
    parents = []
    rank = []
    constructor(k){
        for(let i=0;i<k;i++){
            this.parents[i] = i 
            this.rank[i] = 1 
        }
    }
    find(e){
        while(this.parents[e] !==e){
            // 路径压缩
            this.parents[e] = this.parents[this.parents[e]]
            e = this.parents[e]
        }
        return e
    }
    merge(e1,e2){
        let p1 = this.find(e1)
        let p2 = this.find(e2)
        if(p1 === p2){
            return
        }
        // 基于rank的优化
        if(this.rank[p1] > this.rank[p2]){
            this.parents[p2] = p1
        }else if(this.rank[e1] < this.rank[e2]){
            this.parents[p1] = p2
        }else{
            this.parents[p1] = p2
            this.rank[p2] ++ 
        }
    }
}