繁体   English   中英

找到 3 个点的所有共线

[英]Find all collinear of 3 points

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

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

我没有通过测试,但我还是自己完成了,找不到任何我能理解的解决方案。

这是数据集

[[0, 0], [1, 1], [2, 2], [3, 3], [3, 2], [4, 2], [5, 1]]

数据集的图像在此处输入图像描述

该解决方案应该返回 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, 0], [1, 1], [2, 2], [3, 3], [3, 2], [4, 2], [5, 1]])
    );

我基本上对所有水平线、垂直线和交叉线进行排序(对不起,我找不到正确的英文单词)并计算它们并将它们相加。

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

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

然后得到收集的集合的最大大小。

这种方法是二次的。

 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], [3, 2], [4, 2], [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; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM