javascriptdata-structures

most stones removed with same row or column


I am not able to understand what is logical flaw in my code

I am trying to solve this problem:

947. Most Stones Removed with Same Row or Column

On a 2D plane, we place n stones at some integer coordinate points. Each coordinate point may have at most one stone.

A stone can be removed if it shares either the same row or the same column as another stone that has not been removed.

Given an array stones of length n where stones[i] = [xi, yi] represents the location of the ith stone, return the largest possible number of stones that can be removed.

/**

 * @param {number[][]} stones
 * @return {number}
 */
var removeStones = function (stones) {
    const rowMap = {}
    const colMap = {}
    for (let i = 0; i < stones.length; i++) {
        const [row, col] = stones[i]
        if (!rowMap[row]) rowMap[row] = 0
        if (!colMap[col]) colMap[col] = 0
        rowMap[row] += 1
        colMap[col] += 1
    }
    return findMaxMove(stones, 0, rowMap, colMap)
};

const findMaxMove = (stones, index, rowMap, colMap) => {
    if (index == stones.length) return 0
    const [row, col] = stones[index]
    let isInCol = colMap[col] > 1
    let isInRow = rowMap[row] > 1
    let removedMove = 0
    if (isInCol || isInRow) {
        const colMapCopy = { ...colMap, [col]: colMap[col] - 1 }
        const rowMapCopy = { ...rowMap, [row]: rowMap[row] - 1 }
        removedMove = 1 + findMaxMove(stones, index + 1, rowMapCopy, colMapCopy);
    }
    return Math.max(removedMove, findMaxMove(stones, index + 1, rowMap, colMap))
}

It is passing for some case and not passing for some case:

case where it is not working:

stones = [[0,1],[1,2],[1,3],[3,3],[2,3],[0,2]]
Expected: 5
Output: 4

I got to know from internet that it is common problem to solve using Disjoint set but I wanted to solve with Brute force before I dive into Disjoint set.

Any help please


Solution

  • The failing test case represents this plane:

    . 0 5 .
    . . 1 2
    . . . 4
    . . . 3
    

    As your code removes the stones in order of their index, you'll remove stones 0 and 1 first, leaving stone 5 orphaned:

    . . 5 .
    . . . 2
    . . . 4
    . . . 3
    

    This is not the optimal solution, as you could first remove 0 (like you did), but then first remove 5 before removing 1. And then all stones can be removed.

    Your algorithm is not really brute force, as it leaves out other possibilities. You have implemented an algorithm that could be called greedy, but not brute force. A brute force approach would also try removing the stones in a different order, as the order influences how many stones can be removed.