在 Javascript 中将多个岛屿转换为多个国家的解决方案
Transform a number of islands into a number of countries solution in Javascript
原题说要算岛的个数(把1的实体连成0的海)
例如:
0001
1001
0110
应该return3因为有3个岛。
我设法解决了这个问题:
function countIslands(A) {
const row = A.length;
const col = A[0].length;
const search = (row, col, A) => {
if(row < 0 || col < 0 || row > A.length - 1 || col > A[row].length - 1 || A[row][col] === 0) {
return;
}
A[row][col] = 0;
search(row-1,col,A);
search(row,col-1,A);
search(row+1,col,A);
search(row,col+1,A);
}
let count = 0;
A.forEach((row, index) => {
row.forEach((value, indexI) => {
if(value === 1) {
search(index, indexI, A);
count++;
}
})
})
return count;
}
它工作正常。但这是一种改变它(理想情况下不是很多改变)以使其能够计算国家的方法吗?
例如:
1122
1223
5521
应该return 5 因为矩阵中有 5 个实体。
您可以交出实际值,只查找相邻的相同值。
我为找到的 islands/countries 添加了一些视觉效果。
function countIslands(A) {
const row = A.length;
const col = A[0].length;
const search = (row, col, A, value) => {
if (row < 0 || col < 0 || row >= A.length || col >= A[row].length || A[row][col] !== value) {
return;
}
A[row][col] = 0;
search(row - 1, col, A, value);
search(row, col - 1, A, value);
search(row + 1, col, A, value);
search(row, col + 1, A, value);
}
let count = 0;
A.forEach((row, index) => {
row.forEach((value, indexI) => {
if (value !== 0) {
A.forEach(a => console.log(...a));
console.log('');
search(index, indexI, A, value);
count++;
}
})
})
A.forEach(a => console.log(...a))
return count;
}
console.log(countIslands([[1, 1, 2, 2], [1, 2, 2, 3], [5, 5, 2, 1]]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以通过从左上角到右下角的单次扫描来解决此问题。
它为每个新发现的领土创建一组唯一标识符。
value !== empty && value !== left && value !== top
跟踪当前单元格所属的 ID(按 indices
数组中的索引)
并“合并”实例的 ID,其中 value === left && value === top
(两个索引包含相同的 ID)
所以这张地图中的number of unique IDS
=== number of distinct territories
。
function replace(array, oldValue, newValue) {
//console.log("replace", oldValue, newValue);
for (let i = 0; i < array.length; ++i) {
if (array[i] === oldValue) array[i] = newValue
}
return newValue;
}
function countIslands(rows, empty = "0") {
let prev = []; // previous row to determine the top value
const indices = []; // may contain differrent indices that point to the same ID
const ids = []; // initially unique IDS, will contain dupes when IDs get "merged"
for (let row of rows) {
for (let i = 0; i < row.length; ++i) {
const value = row[i];
if (value === empty) {
continue;
}
// current cell is not "empty"
const top = prev[i] || empty;
const left = row[i - 1] || empty;
if (value === left && value === top) {
// merge ids (think an u-shape where you started at two ends, not knowing in advance that they will meet)
indices[i] = replace(ids, indices[i - 1], indices[i]);
} else if (value === left) {
// current cell belongs to left cell, copy the index
indices[i] = indices[i - 1];
} else if (value !== top) {
// new country, create new id
indices[i] = ids.length;
ids[ids.length] = ids.length; // doesn't matter, as long as it is unique.
}
}
prev = row;
}
//the number of countries === number of distinct IDs left.
return new Set(ids).size;
}
// 9
const map = `
777788
711227
712237
755217
887777`;
/*
// this is as intertwined as it gets,
// 2 spirals
const map = `
3333333333
2222222223
2333333323
2322222323
2323332323
2323232323
2323222323
2323333323
2322222223
2333333333`;
*/
console.log(countIslands(map.trim().split("\n").map(row => [...row.trim()])));
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
原题说要算岛的个数(把1的实体连成0的海)
例如:
0001
1001
0110
应该return3因为有3个岛。
我设法解决了这个问题:
function countIslands(A) {
const row = A.length;
const col = A[0].length;
const search = (row, col, A) => {
if(row < 0 || col < 0 || row > A.length - 1 || col > A[row].length - 1 || A[row][col] === 0) {
return;
}
A[row][col] = 0;
search(row-1,col,A);
search(row,col-1,A);
search(row+1,col,A);
search(row,col+1,A);
}
let count = 0;
A.forEach((row, index) => {
row.forEach((value, indexI) => {
if(value === 1) {
search(index, indexI, A);
count++;
}
})
})
return count;
}
它工作正常。但这是一种改变它(理想情况下不是很多改变)以使其能够计算国家的方法吗?
例如:
1122
1223
5521
应该return 5 因为矩阵中有 5 个实体。
您可以交出实际值,只查找相邻的相同值。
我为找到的 islands/countries 添加了一些视觉效果。
function countIslands(A) {
const row = A.length;
const col = A[0].length;
const search = (row, col, A, value) => {
if (row < 0 || col < 0 || row >= A.length || col >= A[row].length || A[row][col] !== value) {
return;
}
A[row][col] = 0;
search(row - 1, col, A, value);
search(row, col - 1, A, value);
search(row + 1, col, A, value);
search(row, col + 1, A, value);
}
let count = 0;
A.forEach((row, index) => {
row.forEach((value, indexI) => {
if (value !== 0) {
A.forEach(a => console.log(...a));
console.log('');
search(index, indexI, A, value);
count++;
}
})
})
A.forEach(a => console.log(...a))
return count;
}
console.log(countIslands([[1, 1, 2, 2], [1, 2, 2, 3], [5, 5, 2, 1]]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以通过从左上角到右下角的单次扫描来解决此问题。
它为每个新发现的领土创建一组唯一标识符。
value !== empty && value !== left && value !== top
跟踪当前单元格所属的 ID(按 indices
数组中的索引)
并“合并”实例的 ID,其中 value === left && value === top
(两个索引包含相同的 ID)
所以这张地图中的number of unique IDS
=== number of distinct territories
。
function replace(array, oldValue, newValue) {
//console.log("replace", oldValue, newValue);
for (let i = 0; i < array.length; ++i) {
if (array[i] === oldValue) array[i] = newValue
}
return newValue;
}
function countIslands(rows, empty = "0") {
let prev = []; // previous row to determine the top value
const indices = []; // may contain differrent indices that point to the same ID
const ids = []; // initially unique IDS, will contain dupes when IDs get "merged"
for (let row of rows) {
for (let i = 0; i < row.length; ++i) {
const value = row[i];
if (value === empty) {
continue;
}
// current cell is not "empty"
const top = prev[i] || empty;
const left = row[i - 1] || empty;
if (value === left && value === top) {
// merge ids (think an u-shape where you started at two ends, not knowing in advance that they will meet)
indices[i] = replace(ids, indices[i - 1], indices[i]);
} else if (value === left) {
// current cell belongs to left cell, copy the index
indices[i] = indices[i - 1];
} else if (value !== top) {
// new country, create new id
indices[i] = ids.length;
ids[ids.length] = ids.length; // doesn't matter, as long as it is unique.
}
}
prev = row;
}
//the number of countries === number of distinct IDs left.
return new Set(ids).size;
}
// 9
const map = `
777788
711227
712237
755217
887777`;
/*
// this is as intertwined as it gets,
// 2 spirals
const map = `
3333333333
2222222223
2333333323
2322222323
2323332323
2323232323
2323222323
2323333323
2322222223
2333333333`;
*/
console.log(countIslands(map.trim().split("\n").map(row => [...row.trim()])));
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}