LeetCode447. Number of Boomerangs

Description

Given n points in the plane that are all pairwise distinct, a “boomerang” is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k(the order of the tuple matters).

Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive).

Example:
Input: [[0,0],[1,0],[2,0]]
Output: 2
Explanation:
The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]]

my program

思路:創建points.size()*points.size()的數組distance,存放每個點到各個點的距離的平方(距離的話需要開方,產生了浮點數,這裏避免了),對數組的每一行元素進行排序,找出每行中某個元素相同的數目n,然後計數count累加(1+2+...+n)的和

class Solution {
public:
    int sum(int n) //求1~n的和
    {
        int res = 0;
        while(n)
        {
            res += n--;
        }
        return res;
    }

    int numberOfBoomerangs(vector<pair<int, int>>& points) {
        int count = 0;
        if(points.size() <= 2) return count;
        vector<vector<long long> > distance; 
        //points.size()*points.size()的數組
        //存放每個點到各個點的距離的平方(距離的話需要開方,產生了浮點數,這裏避免了)
        for(int i = 0; i<points.size(); i++)    //初始化數組
        {
            vector<long long>temp(points.size(),0);
            distance.push_back(temp);
        }
        for(int i = 0;i<points.size(); i++)     //填充數組(計算距離平方填充)
        {
            for(int j = 0; j<points.size(); j++)
            {
                long long x = points[i].first - points[j].first;
                long long y = points[i].second - points[j].second;
                distance[i][j] = x*x + y*y;
            }
        }

        for(int i = 0;i<points.size(); i++) 
        {
            sort(distance[i].begin(),distance[i].end());
            int j = 0;
            while(j<points.size()-1)
            {
                int n = 0;
                //每行中某個元素相同的數目
                while(j<points.size()-1 && distance[i][j] == distance[i][j+1])
                {
                    n++;
                    j++;
                }
                if( n != 0) count += sum(n)*2;
                j++;
            }
        }
        return count;
    }
};

Submission Details
31 / 31 test cases passed.
Status: Accepted
Runtime: 175 ms
Your runtime beats 92.00% of cpp submissions.

other methods

For each point i, map<distance d, count of all points at distance d from i>.
Given that count, choose 2 (with permutation) from it, to form a boomerang with point i.
[use long appropriately for dx, dy and key; though not required for the given test cases]
Time Complexity: O(n^2)

int numberOfBoomerangs(vector<pair<int, int>>& points) {

    int res = 0;

    // iterate over all the points
    for (int i = 0; i < points.size(); ++i) {

        unordered_map<long, int> group(points.size());

        // iterate over all points other than points[i]
        for (int j = 0; j < points.size(); ++j) {

            if (j == i) continue;

            int dy = points[i].second - points[j].second;
            int dx = points[i].first - points[j].first;

            // compute squared euclidean distance from points[i]
            int key = dy * dy;
            key += dx * dx;

            // accumulate # of such "j"s that are "key" distance from "i"
            ++group[key];
        }

        for (auto& p : group) {
            if (p.second > 1) {
                /*
                 * for all the groups of points, 
                 * number of ways to select 2 from n = 
                 * nP2 = n!/(n - 2)! = n * (n - 1)
                 */
                res += p.second * (p.second - 1);
            }
        }
    }

    return res;
}
int numberOfBoomerangs(vector<pair<int, int>>& points) {
    int booms = 0;
    for (auto &p : points) {
        unordered_map<double, int> ctr(points.size());
        for (auto &q : points)
            booms += 2 * ctr[hypot(p.first - q.first, p.second - q.second)]++;
    }
    return booms;
}

Try each point as the “axis” of the boomerang, i.e., the “i” part of the triple. Group its distances to all other points by distance, counting the boomerangs as we go. No need to avoid q == p, as it’ll be alone in the distance == 0 group and thus won’t influence the outcome.

Submitted five times, accepted in 1059, 1022, 1102, 1026 and 1052 ms, average is 1052.2 ms. The initial capacity for ctr isn’t necessary, just helps make it fast. Without it, I got accepted in 1542, 1309, 1302, 1306 and 1338 ms.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章