【问题标题】:Javascript K Closest Points to Origin in Linear Time?Javascript K在线性时间内最接近原点?
【发布时间】:2020-07-29 20:03:03
【问题描述】:

在线性时间O(N)内解决这个问题有问题吗?我认为解决它的唯一方法是使用 sort(),这给了我 O(NlogN) 时间。

问题: 我们有一个平面上的点列表。找到离原点 (0, 0) 最近的 K 个点。

(这里,平面上两点之间的距离是欧几里得距离。)

您可以按任何顺序返回答案。答案保证是唯一的(除了它的顺序。)

我的解决方案:

/*
    d = sqrt ( (x-0)^2 + (y-0)^2 )
*/

var kClosest = function(points, K) {
    points.sort((a,b) => {
        const d1 = Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2));
        const d2 = Math.sqrt(Math.pow(b[0], 2) + Math.pow(b[1], 2));
        return d1-d2;
    });
    return points.splice(0, K);
};

【问题讨论】:

    标签: javascript time-complexity


    【解决方案1】:

    有一种方法,使用计数排序。

    假设最大 X 和 Y 坐标相当有限,您可以完全跳过使用Math.sqrt。您最终将得到一个 distances 整数值数组,表示每个点到中心的距离的平方。

    然后,您从 0 循环到 the maximum possible distance 通过此数组并打印您找到的每个点,直到找到 K 点。

    这是我的实现(你也许可以让它更漂亮?):

    points = [[-1, 9], [2, 2], [10, 15], [3, 4], [7,5]]
    
    var kClosest = function(points, K) {
        const MAX_X = 100
        const MAX_Y = 100
        const MAX_DISTANCE = MAX_X**2 + MAX_Y**2
    
        let distancesSquared = new Array(MAX_DISTANCE).fill(null).map(() => [])
        for(let point of points) {
            const distanceSquared = point[0]**2 + point[1]**2
            distancesSquared[distanceSquared].push(point)
        }
    
        const result = []
        let pointsLeft = Math.min(points.length, K) // Make sure K isn't greater than the amount of points
        for(let crtDistance = 0; crtDistance <= MAX_DISTANCE; ++crtDistance) {
            while(distancesSquared[crtDistance].length > 0 && pointsLeft > 0) {
                result.push(distancesSquared[crtDistance].pop())
                --pointsLeft
            }
    
            if(pointsLeft === 0) { // Tiny optimisation
                break 
            }
        }
    
        return result
    };
    
    kClosest(points, 3)
    

    【讨论】:

    • 您假设我们的点数不会超过 [100,100]。也不是你的 for 循环中的 while 使得它 O(N^2) 时间复杂度?
    • 是的,fairly limited 我的意思是这些点在范围内([-50; 50],[-50; 50])。在这种情况下,第一个 for 循环可以认为是 O(1); while 循环在最坏的情况下会循环 O(N) 项 - 因此,在这种特殊情况下,算法的复杂度大约为 O(N)。所以,是的,有时问题可以在 O(N) 中解决。 ?
    • 我认为当我们使用大 O 表示法时,我们总是考虑最坏的情况
    • 是的,取决于您的问题的限制。在这种情况下,它总是 O(N)。
    猜你喜欢
    • 2019-06-29
    • 2021-06-09
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 2014-07-11
    相关资源
    最近更新 更多