在网格(二维数组)上查找坐标

时间:2018-09-17 05:17:29

标签: javascript arrays matrix depth-first-search breadth-first-search

我目前正在尝试解决在白板模拟面试中未能解决的问题。我被卡了几次。任何帮助表示赞赏。

问题的措辞如下:

  

给出一个带有灯坐标数组的NxN网格。每个灯在其x轴上的每个正方形,在y轴上的每个正方形以及对角线中的每个正方形(象棋中的女王)都提供照明。给定查询坐标数组,请确定该点是否被照亮。

     

问题在于检查查询时,与该查询相邻或在该查询上的所有指示灯均关闭。如果您访问坐标/单元,请关闭该坐标或相邻坐标中的所有指示灯。如果两个单元格共享相同的边或角,则它们是相邻的。

     
      
  • 编写函数checkLampIllumination(N, lamps, queries)
  •   
  • N:网格的大小
  •   
  • lamps:灯的坐标
  •   
  • queries:要检查网格上的坐标是否点亮
  •   

给出的测试用例是:

N = 8

lamps = [
    [1,6],
    [5,6],
    [7,3],
    [3,2]
]

queries = [
    [4,4],
    [6,6],
    [8,1],
    [3,2],
    [2,3]
]

输出:

['DARK','LIGHT','DARK','DARK','LIGHT']

第二个测试用例:

checkLampIllumination(8, [[4,3],[4,4]], [[3,4],[7,6]])

N = 8

lamps = [
    [4,3],
    [4,4]
]

queries = [
    [3,4],
    [7,6]
]

输出:

['DARK','LIGHT']

这是我目前的状况。我认为当前的解决方案只是创建网格。我真的不知道从这里去哪里。

const checkLampIllumination=(N, lamps, queries) => {
    var gridNxN = []
    var row = []
    for (var i = 1; i < 100; i++) {
        if (i.toString().indexOf('0') !== -1) {
            row.push(i)
            gridNxN.push(row)
            row = []
        } else {
            row.push(i)
        }
    }
}

2 个答案:

答案 0 :(得分:2)

只是为了可视化灯和查询,如果需要,您可以玩pixel art generator

我首先创建一个辅助函数//Craete an object and assign it the existing embedded doc. var item = { houses: req.user.houses }; // add your new address into the existing object item.houses.push({adresse:'Test'}) // $set below updates the whole document along with your new address User.findByIdAndUpdate(req.user.id, { $set: item }, function(err, result) { if (err) { callback(err, undefined); } else if (result) { callback(err, result); } });来检查两个点是否相邻。然后,遍历每个查询(目标方块),并检查是否有任何灯照亮了目标。问题减少到检查以下内容:

  • 灯不相邻,并且至少满足以下条件之一:

  • 灯泡具有相同的X坐标,或者

  • 相同的Y坐标,或

  • 它们在同一对角线上,可以通过查看灯和目标X坐标之间的差是否等于灯和目标Y坐标之间的差来检查。

将其放入代码中,您将得到:

isAdjacent

我不建议事先构建照明的正方形,因为在给定查询的情况下,您将不知道某个照明正方形是否仅由于相邻的灯而具有照明,至少没有遍历所有照明的情况再次点亮-最好在选择查询后只遍历它们一次。

请注意,let lamp = [ [1, 6], [5, 6], [7, 3], [3, 2] ]; const queries = [ [4, 4], [6, 6], [8, 1], [3, 2], [2, 3] ] const isAdjacent = (x1, y1, x2, y2) => Math.abs(x2 - x1) < 2 && Math.abs(y2 - y1) < 2; queries.forEach(([checkX, checkY]) => { const thisSquareIlluminated = lamp.some(([lampX, lampY]) => ( !isAdjacent(checkX, checkY, lampX, lampY) && ( lampX === checkX || lampY === checkY || Math.abs(lampX - checkX) === Math.abs(lampY - checkY) ) )); console.log(thisSquareIlluminated ? 'LIGHT' : 'DARK'); });输入未在任何地方使用-它是红色鲱鱼,除非您还需要检查灯/查询是否也在板上的有效空间中。

答案 1 :(得分:1)

由于我们目前不在接受采访,所以我决定使代码不紧凑,以便于理解。您可以根据需要缩短它。我喜欢这种问题,所以花了我的时间。

我还更新了视觉网格。现在,您可以看到网格变化时的状态。

var lamps = [
    [1,6],
    [5,6],
    [7,3],
    [3,2]
];

var queries = [
    [4,4],
    [6,6],
    [8,1],
    [3,2],
    [2,3]
];

/* ==================== VISUAL GRID ==================== */

function arrayFlatten(array) {
    var result = [];
    array.forEach(function (item) {
        if (item instanceof Array) {
            result = result.concat(arrayFlatten(item));
        } else {
            result.push(item);
        }
    });
    return result;
}

function createGrid(lamps, queries) {
    var grid = document.createElement("table");
    grid.classList.add("grid");
    var gridSize = Math.max.apply(null, arrayFlatten([lamps, queries])) + 1;
    
    document.body.appendChild(grid);
    
    // create cells
    for (var i = 0; i < gridSize; i++) {
        var row = document.createElement("tr");
        for (var j = 0; j < gridSize; j++) {
            var cell = document.createElement("td");
            row.appendChild(cell);
        }
        grid.appendChild(row);
    }
    
    // add lamps
    lamps.forEach(lamp => grid.rows[lamp[1]].cells[lamp[0]].classList.add("lamp"));

    var illuminatedRows = Array.from(new Set(lamps.map(([lampX, lampY]) => lampY)));
    var illuminatedCols = Array.from(new Set(lamps.map(([lampX, lampY]) => lampX)));
    illuminatedRows.sort();
    illuminatedCols.sort();

    // add lights
    // horizontal
    for (var i = 0; i < grid.rows.length; i++) {
        if (illuminatedRows.includes(i)) {
            Array.from(grid.rows[i].cells).forEach(cell => cell.classList.add("horizontal-light"));
        }
    }
    // vertical
    for (var i = 0; i < grid.rows.length; i++) {
        for (var j = 0; j < grid.rows[i].cells.length; j++) {
            if (illuminatedCols.includes(j)) {
                grid.rows[i].cells[j].classList.add("vertical-light");
            }
        }
    }
    // diagonal
    for (var i = 0; i < grid.rows.length; i++) {
        for (var j = 0; j < grid.rows[i].cells.length; j++) {
            var x = j;
            var y = i;
            lamps.forEach(function (lamp) {
                if (isDiagonal(lamp[0], lamp[1], x, y)) {
                    grid.rows[i].cells[j].classList.add("diagonal-light");
                }
            });
        }
    }
    
}

createGrid(lamps, queries);

/* ==================== CALCULATION ==================== */

function isHorizontal(y1, y2) {
    return y1 == y2;
}

function isVertical(x1, x2) {
    return x1 == x2;
}

function isDiagonal(x1, y1, x2, y2) {
    return Math.abs(x1 - x2) == Math.abs(y1 - y2);
}

function isIlluminated(queryX, queryY, lampX, lampY) {
    return isHorizontal(queryY, lampY) || isVertical(queryX, lampX) || isDiagonal(queryX, queryY, lampX, lampY);
}

function isAdjacent(x1, y1, x2, y2) {
    return Math.abs(x2 - x1) < 2 && Math.abs(y2 - y1) < 2
}

// check every lamp for each query
function checkLamps(lamps, queryX, queryY) {
    // store checks for each lamp for a query
    var checks = [];
    // loop every lamp
    for (var i = lamps.length - 1; i >= 0; i--) {
        var lampX = lamps[i][0];
        var lampY = lamps[i][1];
        // check if the target cell is adjacent to the current lamp
        if (isAdjacent(queryX, queryY, lampX, lampY)) {
            console.log("Query (" + [queryX, queryY].join() + ") is adjacent to lamp (" + [lampX, lampY].join() + "). Removing this lamp.");
            // lamp is adjacent; remove it
            lamps.splice(i, 1);
            // create a grid with the new state (for visual purposes)
            createGrid(lamps, queries);
            // skip this lamp
            continue;
        } else {
            // storing the check for the current lamp
            checks.push(isIlluminated(queryX, queryY, lampX, lampY));
        }
    }
    // if all checks are false, it's dark
    // if there's even a single true, that means the cell is illuminated by a lamp
    if (checks.includes(true)) {
        console.log("(" + [queryX, queryY].join() + ") is LIGHT");
    } else {
        console.log("(" + [queryX, queryY].join() + ") is DARK");
    }
}

function checkLampIllumination(lamps, queries) {
    // create a local copy of lamps because it'll (might) mutate
    var lamps = lamps.slice();
    // loop queries
    queries.forEach(([queryX, queryY]) => checkLamps(lamps, queryX, queryY));
}

checkLampIllumination(lamps, queries);
.grid {
    background-color: black;
    border-collapse: collapse;
    margin-right: 1em;
    float: left;
}
.grid td {
    width: 25px;
    height: 25px;
    border: 1px solid hsl(0, 0%, 50%);
}
.grid td.horizontal-light,
.grid td.vertical-light,
.grid td.diagonal-light {
    background-color: hsla(0, 0%, 80%, .33);
}
.grid td.horizontal-light.vertical-light,
.grid td.horizontal-light.diagonal-light,
.grid td.vertical-light.diagonal-light {
    background-color: hsla(0, 0%, 80%, .45);
}
.grid td.horizontal-light.vertical-light.diagonal-light {
    background-color: hsla(0, 0%, 80%, .6);
}
.grid td.lamp {
    background-color: hsl(0, 0%, 100%) !important;
}