【leetcode】447 Number of Boomerangs

本文详细解析了LeetCode上编号为“回旋镖数量”的题目,提供了两种高效算法解决方案,一种利用unordered_map存储距离平方及出现次数,另一种通过排序和计数找出连续相等距离的匹配次数。两种方法均能达到O(n^2)的时间复杂度。

题目说明

https://leetcode-cn.com/problems/number-of-boomerangs/description/
给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。找到所有回旋镖的数量。

解法1

使用unordered_map。
第一层循环来遍历i的值
第二层循环,要找到所有与i的距离与对应次数
unordered_map来保存每种距离的平方与对应次数
次数times大于等于2的则有回旋镖。
第一个点可能性为times,第二个点可能性times - 1,则最终的数量为times * (times - 1)
时间复杂度:O(n^2)

int numberOfBoomerangs(vector<pair<int, int>>& points) {
    int count = 0;
    unordered_map<double,int> m;
    for (int i = 0; i < points.size(); i ++)
    {
        for (int j = 0;j < points.size(); j ++)
        {
            if (j != i)
            {
                //以距离的平方为键,次数为值
                double var = pow(points[j].first - points[i].first,2)+pow(points[j].second - points[i].second,2);
                m[var]++;
            }
        }
        auto iter=m.begin();
        while(iter!=m.end())
        {
            if ((*iter).second >= 2)
                count += (iter->second) * (iter->second - 1);//第一个点可能性为second,第二个点可能性second - 1
            iter++;
        }
        m.clear();
    }

    return count;
}

解法2

保存所有距离,并作排序。若距离连续都相等,则为所要找的匹配次数,计算总数
时间复杂度:O(n^2)

int numberOfBoomerangs(vector<pair<int, int>>& points) {
    int res = 0;
    vector<double> dis(points.size(),0);
    for (int i = 0; i < points.size(); i ++)
    {
        //取出本轮所有距离的值
        for (int j = 0;j < points.size(); j ++)
        {
            dis[j] = pow(points[j].first - points[i].first,2)+pow(points[j].second - points[i].second,2);
        }
        //对距离作排序
        sort(dis.begin(),dis.end());
        int matchcount = 1;
        for (int j = 1;j < points.size(); j ++)
        {
            if (dis[j] == dis[j - 1]){//距离相等
                matchcount += 1;
            }else{//距离不相等时,对相等距离计算总数
                res += matchcount * (matchcount - 1);
                matchcount = 1;
            }
        }
        //对于最后几个数据距离都相等的处理
        res += matchcount * (matchcount - 1);
    }

    return res;
}

转载于:https://www.cnblogs.com/JesseTsou/p/9528234.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值