一、问题
二、分析
这个跟在图上找寻每个节点到各个节点之间的最短路径相同,可以利用弗洛伊德算法,不过时间复杂度过高,为此由于问题的特殊性可以采用BFS获得DFS + 记忆搜索,这里只写出用弗洛伊德算法写出的代码。另外就是棍子编号和端点编号的转换问题,这个可以自己去推导,我直接写上了。
三、代码
/**
* @param {number} height
* @param {number} width
* @param {number[]} indices
* @return {number[]}
*/
function getVeByStickNo(stick_no, width) {
let E_origin = stick_no % (2*width + 1);
let Layer = Math.floor(stick_no / (2*width + 1));
let v1 = 0;
let v2 = 0;
if(E_origin - width < 0) { //横向的火柴棍
v1 = E_origin; v2 = v1 + 1;
v1 = v1 + Layer * (width + 1); v2 = v1 + 1;
} else { //纵向的火柴棍
v1 = E_origin - width; v2 = E_origin + 1;
v1 = v1 + Layer * (width + 1); v2 = v2 + Layer * (width + 1);
}
return [v1,v2];
}
var lightSticks = function(height, width, indices) {
//弗洛伊德算法,相当于求每个节点之间的最短距离,然后选择最长节点中的最短节点
var v = [];
var e = [];
var MAX = 99999;
var ans = [];
let v_count = (height + 1) * (width+1);
let e_count = (height * (width + 1)) + (width * (height + 1));
for(let i = 0; i < v_count; i++) {
v[i] = 1;
}
for(let j = 0; j < v_count; j++) {
if(e[j] == undefined) {
e[j] = [];
}
for(let k = 0; k < v_count; k++) {
if(e[k] == undefined) { e[k] = [];}
if(k == (j + width + 1)
|| (k == (j + 1) && (Math.floor(k / (width+1)) == Math.floor(j / (width+1))))
|| k == (j - width - 1)
|| (k == j - 1 && (Math.floor(k / (width+1)) == Math.floor(j / (width+1))))
) {
e[j][k] = e[k][j] = 1;
} else {
e[j][k] = e[k][j] = MAX;
}
}
}
for(let u = 0; u < indices.length; u++) {
let t_v = getVeByStickNo(indices[u], width);
e[t_v[0]][t_v[1]] = e[t_v[1]][t_v[0]] = MAX;
}
for(let a = 0; a < v_count; a++) {
let top = a - width - 1;
let bottom = a + width + 1;
let right = a + 1;
let left = a - 1;
let count = 0;
if(e[a][top] == undefined || e[a][top] == MAX) {
count++;
}
if(e[a][bottom] == undefined || e[a][bottom] == MAX) {
count++;
}
if(e[a][right] == undefined || e[a][right] == MAX) {
count++;
}
if(e[a][left] == undefined || e[a][left] == MAX) {
count++;
}
if(count == 4) {
v[a] = 0;
}
}
let visited = [];
//邻接矩阵方法 时间复杂度高
let v_queue = [];
v_queue.push(0);
while(v_queue.length > 0) {
let r_node = v_queue.pop();
if(visited[r_node] != undefined) {
continue;
}
visited[r_node] = 1;
v[r_node] = 0;
for(let b = 0; b < e[r_node].length; b++) {
if(e[r_node][b] == MAX || r_node == b) {
continue;
}
for(let d = 0; d < e[r_node].length; d++) {
e[d][b] = e[b][d] = Math.min(e[b][r_node] + e[r_node][d], e[b][d]);
if(r_node != d) {
e[d][r_node] = e[r_node][d] = Math.min(e[r_node][b] + e[b][d], e[r_node][d]);
}
}
v_queue.push(b);
}
}
for(let a2 = 0; a2 < v.length; a2++) {
if(v[a2] > 0) {
return [];
}
}
let paths = [];
for(let o = 0; o < e.length; o++) {
let longestPath = 0;
for(let p = 0; p < e[o].length; p++) {
if(e[o][p] >= MAX) {
continue;
}
longestPath = Math.max(e[o][p],longestPath);
}
if(longestPath != MAX && longestPath != 0) {
if(paths[longestPath] == undefined) {
paths[longestPath] = [];
}
paths[longestPath].push(o);
}
}
if(paths.length > 0) {
len_paths = Object.keys(paths);
ans = paths[parseInt(len_paths[0])];
}
return ans;
};