1102. 得分最高的路径
给定一个 m x n 的整数矩阵 grid,返回从 (0,0) 开始到 (m - 1, n - 1) 在四个基本方向上移动的路径的最大 分数 。
一条路径的 分数 是该路径上的最小值。
- 例如,路径
8 → 4 → 5 → 9的得分为4。
示例 1:
输入: grid = [[5,4,5],[1,2,6],[7,4,6]]
输出: 4
解释: 得分最高的路径用黄色突出显示。
示例 2:
输入: grid = [[2,2,1,2,2,2],[1,2,2,2,1,2]]
输出: 2
示例 3:
输入: grid = [[3,4,6,3,4],[0,2,1,1,7],[8,8,3,2,7],[3,2,4,9,8],[4,1,2,0,0],[4,6,5,4,3]]
输出: 3
提示:
m == grid.lengthn == grid[i].length1 <= m, n <= 1000 <= grid[i][j] <= 109
/**
* @param {number[][]} grid
* @return {number}
*/
var maximumMinimumPath = function(grid){
const m = grid.length; // 行
const n = grid[0].length; // 列
const queue = [];
const unionFind = new UnionFind(m * n);
for(let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
queue.push([i, j, grid[i][j]]);
}
}
queue.sort((a, b) => a[2] - b[2]); // 按照格子值大小进行排序
const isSetColor = grid.map(item => item.map( value => 0));
let maxValue = Math.min(grid[0][0], grid[m - 1][n - 1]);
while (!unionFind.checkUnion(0, m * n -1)) {
const [x, y, value] = queue.pop();
maxValue = Math.min(value, maxValue);
isSetColor[x][y] = 1;
if (x - 1 >= 0 && isSetColor[x - 1][y] === 1) {
unionFind.union(x * n + y, (x - 1) * n + y);
}
if (x + 1 <= m - 1 && isSetColor[x + 1][y] === 1) {
unionFind.union(x * n + y, (x + 1) * n + y);
}
if (y - 1 >= 0 && isSetColor[x][y - 1] === 1) {
unionFind.union(x * n + y, x * n + y - 1);
}
if(y + 1 <= n - 1 && isSetColor[x][y + 1] === 1) {
unionFind.union(x * n + y, x * n + y + 1);
}
}
return maxValue;
}
class UnionFind {
constructor(count) {
this.count = count;
this.parents = [];
this.sizes = new Array(count).fill(1);
this.init();
}
init() {
for (let i = 0; i < this.count; i++) {
this.parents[i] = i;
}
}
find(node) {
let curNode = node;
while (this.parents[curNode] !== curNode) {
this.parents[curNode] = this.parents[this.parents[curNode]];
curNode = this.parents[curNode];
}
return curNode;
}
union(left, right) {
const leftRoot = this.find(left);
const rightRoot = this.find(right);
if (leftRoot !== rightRoot) {
if (this.sizes[leftRoot] < this.sizes[rightRoot]) {
this.parents[leftRoot] = rightRoot;
this.sizes[rightRoot] += this.sizes[leftRoot];
} else {
this.parents[rightRoot] = leftRoot;
this.sizes[leftRoot] += this.sizes[rightRoot];
}
this.count--;
return true;
}
return false;
}
checkUnion(left, right) {
return this.find(left) === this.find(right);
}
}