并查集-得分最高的路径

232 阅读1分钟

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.length
  • n == grid[i].length
  • 1 <= m, n <= 100
  • 0 <= 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);
	}
}