找到所有3点共线

我进行了一次工作面试测试,其中的问题是找到数据集中3个点的所有共线数据点。

wolframalpha.com/input/?i=collinear+lines

我没有通过测试,但仍然独自完成测试,找不到我能理解的解决方案。

这是数据集

[[0,0],[1,1],[2,2],[3,3],[4,[5,1]]
数据集的图像

找到所有3点共线

该解决方案应返回6所执行的操作,但我只是想知道我是否获得了最佳的解决方案。

我的解决方案:

    /**
     * Will return the amount of lines of 3 points or can made with 3 unique points
     * @param {number} dotsInLine
     *
     *  @returns {number} of lines of 3 points found
     */
    function countLineOf3(dotsInLine) {
        if (dotsInLine === 3) return 1;
        if (dotsInLine > 3) return (dotsInLine - 3) * dotsInLine;
        return 0;
    }

    /**
     * will go trough the array of found points on 1 axes and return the count of 3 point lines found
     * @param {array} foundInArr
     * @param {object} matrix
     *
     * @returns {number}
     */
    function foundInAddToCount(foundInArr,matrix) {
        let count = 0;
        for (let i = 0; i < foundInArr.length; i++) {
            count += countLineOf3(matrix[foundInArr[i]]);
        }

        return count;
    }

    function solution(A) {
        let count = 0;
        let maxX = 0;
        let maxY = 0;
        const xStrait = {};
        const xStraitFound = [];
        const yStrait = {};
        const yStraitFound = [];

        const lineUp = {};
        const lineUpFound = [];
        const lineDown = {};
        const lineDownFound = [];

        for (let i = 0; i < A.length; i++) {
            if (maxX < A[i][0]) maxX = A[i][0];
            if (maxY < A[i][1]) maxY = A[i][1];

            // find strait vertical points
            if (!xStrait[A[i][0]]) xStrait[A[i][0]] = 0;
            xStrait[A[i][0]]++;
            if (xStrait[A[i][0]] === 3) xStraitFound.push(A[i][0]);
            // find strait horizontal points
            if (!yStrait[A[i][1]]) yStrait[A[i][1]] = 0;
            yStrait[A[i][1]]++;
            if (yStrait[A[i][1]] === 3) yStraitFound.push(A[i][1]);

            // find points bottom left to top right
            const x = A[i][0];
            const y = A[i][1];

            const xMinY = x - y;
            const yMinx = y - x;
            //middle line
            let key;
            if (xMinY >= 0 && yMinx >= 0) {
                key = `${xMinY}${yMinx}`;
            } else if (xMinY >= 0 && yMinx < 0) {
                // y zero UP
                key = `${xMinY}0`;
            } else if (xMinY < 0 && yMinx >= 0) {
                // x zero UP
                key = `0${yMinx}`;
            }

            if (key) {
                if (!lineUp[key]) lineUp[key] = 0;
                lineUp[key]++;
                if (lineUp[key] === 3) lineUpFound.push(key);
            }

            const xPlusY = x + y;
            //find points top left to bottom right
            if (!lineDown[`0${xPlusY}`]) lineDown[`0${xPlusY}`] = 0;
            lineDown[`0${xPlusY}`]++;
            if (lineDown[`0${xPlusY}`] === 3) {
                lineDownFound.push(`0${xPlusY}`);
            }
        }

        count += foundInAddToCount(xStraitFound,xStrait);
        count += foundInAddToCount(yStraitFound,yStrait);

        count += foundInAddToCount(lineUpFound,lineUp);
        count += foundInAddToCount(lineDownFound,lineDown);
        return count;
    }

    console.log(
        solution([[0,1]])
    );

我基本上对所有水平,垂直和交叉线进行排序(对不起,我找不到正确的英语单词),然后对它们进行计数并加起来。

因此,如果有人有任何提示,请告诉我。

zhanghaowl 回答:找到所有3点共线

您可以采用蛮力方法收集成对的点及其斜率/截距。

然后获得所收集集合的最大大小。

这种方法是二次方的。

function getAB([x1,y1],[x2,y2]) { // slope/intercept of y = ax + b
    var a;
    return x1 === x2
        ? [Infinity,x1]
        : [a = (y2 - y1) / (x2 - x1),y1 - a * x1];
}

var points = [[0,0],[1,1],[2,2],[3,3],[4,[5,1]],collection = {},usedPoints = new Set;

points.forEach((p1,i,a) => {
    if (usedPoints.has(p1.toString())) return;
    a.slice(i + 1).forEach((p2,j,b) => {
        if (usedPoints.has(p2.toString())) return;
        var key = JSON.stringify(getAB(p1,p2));
        collection[key] = collection[key] || new Set;
        collection[key].add(p1);
        collection[key].add(p2);
        usedPoints.add(p1.toString());
    });
});

console.log(Math.max(...Object.values(collection).map(s => s.size)));

console.log(Object.entries(collection).map(([k,v]) => [k,[...v].map(w => w.join(' '))]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

本文链接:https://www.f2er.com/3144274.html

大家都在问