活跃农民
- 积分
- 511
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2013-6-5
- 最后登录
- 1970-1-1
|
1230 2. Number of Distinct Islands II
/**
* @param {number[][]} grid
* @return {number}
*/
var numDistinctIslands2 = function(grid) {
// so how it works is:
// loop the grid, dfs each one with a list
// after the dfs, if the list is valid, then add canonical value of this list to the set
// in the end, return the size of the set
// how to dfs:
// check self, up, down, left, right, visit one and set itself to 0 (or use set)
// for each point, add [x, y] to the list
// how to get canonical value:
// we have the list right?
// loop 0 - 7, 8 times, for each code, we have a function to return the current form of the point
// for each point of the list, loop under the code loop, get the new list
// now for each list, we get the anchor point of that list, get the relative points representation of the list
// it is still a point list
// now we have a relative list, now we calc this list into a value, why not just concatenate everything into a str?
// that should work. now we have the string key for each possible list, we get the smallest of the 8 keys and add it to the
// set
if (grid == null || grid.length === 0 || grid[0].length === 0) {
return 0;
}
const rowLen = grid.length;
const colLen = grid[0].length;
const set = new Set();
for (let i = 0; i < rowLen; i++) {
for (let j = 0; j < colLen; j++) {
const list = [];
dfs(i, j, list);
if (list.length > 0) {
const val = getCanonical(list);
set.add(val);
}
}
}
return set.size;
function dfs (i, j, list) {
if (i >= 0 && i < rowLen && j >= 0 && j < colLen && grid[i][j] === 1) {
grid[i][j] = 0;
list.push([i, j]);
const moves = [[0, 1], [0, -1], [-1, 0], [1, 0]];
for (let move of moves) {
const x = i + move[0];
const y = j + move[1];
dfs(x, y, list);
}
}
}
function getCanonical (list) {
let minVal = null;
for (let i = 0; i < 8; i++) {
const newList = [];
for (let point of list) {
const newPoint = getNewPoint(point, i);
newList.push(newPoint);
}
// !!! for each of the lists, all of the points in the list, we need to normalize them
// find the origin point and get the relative value of all points to this origin point
let minX = Infinity;
let minY = Infinity;
for (let [x, y] of newList) {
minX = Math.min(x, minX);
minY = Math.min(y, minY);
}
const val = newList.map(([x, y]) => [x - minX, y - minY]).map(([x, y]) => `${x}:${y}`).sort().join(',');
if (minVal == null || val < minVal) {
minVal = val;
}
}
return minVal;
}
function getNewPoint ([i, j], code) {
switch (code) {
case 0:
return [i, j];
case 1:
return [i, -j];
case 2:
return [-i, j];
case 3:
return [-i, -j];
case 4:
return [j, i];
case 5:
return [j, -i];
case 6:
return [-j, i];
case 7:
return [-j, -i];
default:
throw new Error('No such type');
}
}
}; |
|