【leetcode 447. 回旋镖的数量】审慎思考与推倒重来

news2024/11/16 8:33:31

447. 回旋镖的数量

题目描述

给定平面上 **n **对 互不相同 的点 points ,其中 points[i] = [xi, yi]回旋镖 是由点 (i, j, k) 表示的元组 ,其中 ij 之间的距离和 ik 之间的欧式距离相等(需要考虑元组的顺序)。

返回平面上所有回旋镖的数量。

原始思路

根据题目描述,所谓回旋镖就是对于一个点i,存在另外两个点到该点的距离相等

以下图为例,点(0,0)(0,2)(2,0)的距离是相通的,这就是一个回旋镖。同样的,点(2,2)(0,2)(2,0)也构成一个回旋镖。

请添加图片描述

大概理解题目的含义后,最直接的想法就是遍历,通过三重遍历分辨判断是否为回旋镖,最后的统计数目就是需要的结果。代码实现如下:

class Solution {
private:
    // 判断点i与点j、点k是否构成回旋镖
    // ps:这里省略了开方运算
    bool isBoomeranges(vector<int>& i, vector<int>& j, vector<int>& k) {
        return ((j[1] - i[1]) * (j[1] - i[1])) + ((j[0] - i[0]) * (j[0] - i[0])) == ((k[1] - i[1]) * (k[1] - i[1])) + ((k[0] - i[0]) * (k[0] - i[0]));
    }
public:
    int numberOfBoomerangs(vector<vector<int>>& points) {
        int res = 0;
        int pointNum = points.size();
        for(int i = 0;i < pointNum;++i) {
            for(int j = 0;j < pointNum;++j) {
                for(int k = 0;k < pointNum;++k) {
                    if(i == j || i == k || j == k) {
                        // 同一个点不算
                        continue;
                    }
                    if(isBoomeranges(points[i], points[j], points[k])) {
                        ++res;
                    }
                }
            }
        }
        return res;
    }
};

三重循环,不出意外地超时了……

image.png

试图挽回,空间换时间

三重循环每次都要计算距离,肯定是做了很多重复运算的,或许可以用空间换时间,

尝试代码如下:

class Solution {
public:
    int numberOfBoomerangs(vector<vector<int>>& points) {
        int res = 0;
        int pointNum = points.size();
        vector<vector<long>> dis(pointNum, vector<long>(pointNum, 0)); // 记录点与点之间的“距离”
        for(int i = 0;i < pointNum;++i) {
            for(int j = i + 1;j < pointNum;++j) {
                dis[j][i] = dis[i][j] = ((points[j][1] - points[i][1]) * (points[j][1] - points[i][1])) + ((points[j][0] - points[i][0]) * (points[j][0] - points[i][0]));
            }
        }
        for(int i = 0;i < pointNum;++i) {
            for(int j = 0;j < pointNum;++j) {
                for(int k = 0;k < pointNum;++k) {
                    if(i == j || i == k || j == k) {
                        continue;
                    }
                    if(dis[i][j] == dis[i][k]) {
                        ++res;
                    }
                }
            }
        }
        return res;
    }
};

结果从通过25个测试用例提升到通过28个。改善了,但又没完全改善。

image.png

到这里,意识到应该是解决方案本身的时间复杂度 O ( n 3 ) O(n^3) O(n3)就太高了。

回归本源,方法为王

虽然上面的思路简单易懂,但也把我带入“歧途”,没有深入审视题目中的含义。

所以遍历思路走到尽头后,不得不重新审视题目。

三重循环中有很多计算是重复的,还是以开头的例子做讲解,对于点(1,1),它需要分别判断:

  1. (0,0)(0,2)是否构成回旋镖
  2. (0,0)(2,2)是否构成回旋镖
  3. (0,0)(2,0)是否构成回旋镖
  4. (0,2)(0,0)是否构成回旋镖
  5. (0,2)(2,2)是否构成回旋镖
  6. (0,2)(2,0)是否构成回旋镖
  7. (2,2)(0,0)是否构成回旋镖
  8. (2,2)(0,2)是否构成回旋镖
  9. (2,2)(2,0)是否构成回旋镖
  10. (2,0)(0,0)是否构成回旋镖
  11. (2,0)(0,2)是否构成回旋镖
  12. (2,0)(2,2)是否构成回旋镖

在这个过程中,(1,1)(0,0)(0,2)(2,2)(2,0)的距离,分别被算了6遍。

但实际上,(1,1)到这四个点的距离都是相同的,任取两个点都能和(1,1)构成回旋镖,再加上顺序敏感的题目要求(既 [ ( 1 , 1 ) , ( 0 , 0 ) , ( 0 , 2 ) ] [(1,1),(0,0),(0,2)] [(1,1),(0,0),(0,2)] [ ( 1 , 1 ) , ( 0 , 2 ) , ( 0 , 0 ) ] [(1,1),(0,2),(0,0)] [(1,1),(0,2),(0,0)]是两个回旋镖),利用排列数计算就能替代多余计算。

whiteboard_exported_image-7.png

所以,对于某个点i,只需统计其他点与i之间的距离,然后利用排列数就可以计算出回旋镖的数目。
比如上面的例子中,距离为 2 \sqrt{2} 2 的点对有4个,那么 A 4 2 = 4 × 3 = 12 A^2_4 = 4 \times 3 = 12 A42=4×3=12

算法步骤:

  1. 遍历所有点
  2. 对于某个点i,统计与其他点的距离长度
  3. 对每个距离长度的数目,计算排列数
  4. 所有排列数之和即为答案
class Solution {
private:
    int distance(const vector<int>& p1, const vector<int>& p2) {
        // 计算两点之间的“距离”
        return (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]);
    }
public:
    int numberOfBoomerangs(vector<vector<int>>& points) {
        int res = 0;
        int pointNum = points.size();
        for(int i = 0;i < pointNum;++i) {
            // 遍历所有点
            unordered_map<int, int> disNumMp;
            for(int j = 0;j < pointNum;++j) {
                // 统计该点与其他之间距离长度的数目
                // 只有该点自己到自己的长度为0,所以0对应的数目一定为0,不影响最终结果计算,无需剔除
                ++disNumMp[distance(points[i], points[j])];
            }
            for(auto it = disNumMp.begin();it != disNumMp.end();++it) {
                // 计算排列数
                res += (it->second * (it->second - 1));
            }
        }
        return res;
    }
};

小感悟

有些时候,人容易对一开始选择的路径产生依赖,不推倒重来就难以跳脱。

审慎的思考和选择或许可以避免弯路,但更多时候还是要走到南墙才能意识到选择的对错。

所以,要有审慎选择的过程,也要有推倒重来的勇气!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1369167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

remote-ssh如何离线下载历史版本

remote-ssh离线下载任意历史版本方法&#xff0c;简单有效 很多小伙伴都会遇到这样的问题&#xff0c;由于内网服务器中安装的vs code版本较低&#xff0c;比如1.62.0版本&#xff0c;官网发布的version history 只展示最新的五个版本&#xff0c;还是太高了&#xff0c;导致下…

C#,入门教程(12)——数组及数组使用的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(11)——枚举&#xff08;Enum&#xff09;的基础知识和高级应用https://blog.csdn.net/beijinghorn/article/details/123917587 数组是一种数据集合&#xff0c;是一组完全相同的、按顺序存放的数据。 需要记住数组的几个特征&…

P1003 [NOIP2011 提高组] 铺地毯————C

目录 [NOIP2011 提高组] 铺地毯题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 解题思路Code运行结果 [NOIP2011 提高组] 铺地毯 题目描述 为了准备一个独特的颁奖典礼&#xff0c;组织者在会场的一片矩形区域&#xff08;可看做…

MT6785安卓核心板_联发科MTK6785/Helio G95/曦力G95核心板定制

MT6785安卓核心板是基于MT6785(Helio G95)处理器&#xff0c;具备八核处理器结构&#xff0c;包括2颗主频为2.05GHz的Cortex A76处理器和6颗主频为2.0GHz的Cortex A55处理器&#xff0c;以及六颗Cortex-A55处理器。而在GPU方面&#xff0c;采用了Arm Mali-G76 MC4&#xff0c;频…

Modbus转Profinet网关揭秘!升级工业自动化!

Modbus转Profinet网关&#xff08;XD-MDPN100/200&#xff09;通过Modbus协议和Profinet协议之间的转换&#xff0c;实现了不同设备之间的通信。Modbus是一种常用的串行通信协议&#xff0c;而Profinet是一种基于以太网的工业通信协议。随着工业自动化的不断发展&#xff0c;Mo…

3.6 QUERYING DEVICE PROPERTIES

我们关于将执行资源分配给区块的讨论提出了一个重要问题。我们如何确定可用资源的数量&#xff1f;当CUDA应用程序在系统上执行时&#xff0c;它如何确定设备中的SM数量以及可以分配给每个SM的块和线程数量&#xff1f;可能与执行CUDA应用程序相关的其他资源尚未讨论。一般来说…

12.8-1.8

2023.12.8 redis容器 docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf redis.conf不存在&#xff0c;需先在宿主机创建该目录下文件&#xff0c…

《亚太教育》是什么级别的期刊?是正规期刊吗?能评职称吗?

《亚太教育》主要发表教育理论研究、教育教学实践、学校管理、学科教育、科研管理等学术论文以及其他与教育教学相关的学术论文和研究成果,现征集教育管理以及各学科优秀论文。欢迎.各位教师、教育工作者及高校学生踊跃投稿。 收录情况&#xff1a;知网万方维普收录 投稿方式&a…

主播职业发展

主播作为当今互联网时代的新兴职业&#xff0c;拥有着广阔的发展前景和无限的可能性。为了在竞争激烈的市场中脱颖而出&#xff0c;主播需要不断提升自己的专业技能&#xff0c;拓展知识领域&#xff0c;增强互动能力&#xff0c;积累粉丝基础&#xff0c;寻求合作机会&#xf…

实现导航栏吸顶操作

一、使用VueUse插件 // 安装 npm i vueuse/core二、点击搜索useScroll 2.1搜索结果如图 三、使用 // 这是示例代码 import { useScroll } from vueuse/core const el ref<HTMLElement | null>(null) const { x, y, isScrolling, arrivedState, directions } useSc…

TS2307: Cannot find module ‘./App.vue‘ or its corresponding type declarations.

目录 1. 问题描述2. 解决方案一&#xff1a;VSCode Volar&#xff08;官方推荐&#xff09;3. 解决方案二&#xff1a;WebStorm 2023.2 &#xff08;官方推荐&#xff09;4. 解决方案三&#xff1a;禁用严格类型检查选项&#xff08;不推荐&#xff09;5. 解决方案四&#xff…

redhat+ oracle 11.2.0.4 RAC 搭建 dataguard

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; redhat oracle 11.2.0.4 RAC 搭建 dataguard 1.安装环境 主机名 OS DB SID db_name db_unique_name rac1 Redhat7 11.2.0.4 orcl1 orcl o…

用React给XXL-JOB开发一个新皮肤(一):环境搭建和项目初始化

目录 一. 简述二. Fork 项目三. 搭建开发环境四. 初始化皮肤项目五. 添加相关依赖六. 预览 一. 简述 大名鼎鼎的 xxl-job 任务调度中心我们应该都使用过&#xff0c;项目地址&#xff1a;xxl-job。它是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单…

XREAL推出其新款AR眼镜:XREAL Air 2 Ultra,体量轻内置音效

这款眼镜堪称科技的杰作&#xff0c;它以钛合金为框架&#xff0c;尽显轻盈与精致。配备的双3D环境传感器&#xff0c;宛如双眼般敏锐&#xff0c;能精准捕捉头部运动&#xff0c;让你在虚拟与现实间自由穿梭。120Hz的超高刷新率与500尼特的亮度&#xff0c;让你在4米之外感受1…

tcp/ip协议2实现的插图,数据结构6 (24 - 章)

(142) 142 二四1 TCP传输控制协议 tcpstat统计量与tcp 函数调用链 (143) 143 二四2 TCP传输控制协议 宏定义与常量值–上 (144) 144 二四3 TCP传输控制协议 宏定义与常量值–下 (145) 145 二四4 TCP传输控制协议 结构tcphdr,tcpiphdr (146) 146 二四5 TCP传输控制协议 结构 tcp…

服务端性能测试——性能测试体系

目录&#xff1a; 1.性能测试介绍 性能测试介绍性能体系&#xff1a;性能测试与分析优化&#xff1a;行业流行性能压测工具介绍行业流行性能监控工具介绍行业流行性能剖析工具介绍性能测试流程与方法性能测试计划 计划&#xff1a;DAU&#xff0c;PV(perday)&#xff0c;订单量…

混淆技术概论

混淆技术概论 引言 在逆向工程领域&#xff0c;混淆技术是一种非常重要的技术手段&#xff0c;通过打破人们的思维惯性&#xff0c;使得逆向分析变得更加困难。本文将会介绍混淆技术的概念、分类及其应用&#xff0c;以及如何使用IPA Guard进行iOS IPA重签名。 混淆技术概述…

2024 运维监控方案解读

WGCLOUD监控系统是一款免费开源的运维工具&#xff0c;具有部署简单&#xff0c;上手容易&#xff0c;轻量高效&#xff0c;性能突出&#xff0c;对新手友好&#xff0c;安全稳定&#xff0c;私有化部署等特点 1、WGCLOUD可以监控大部分的主机和服务器&#xff0c;比如Linux、…

Java索引优先队列设计思路与实现

Java 学习面试指南&#xff1a;https://javaxiaobear.cn 1、实现思路 存储数据时&#xff0c;给每一个数据元素关联一个整数&#xff0c;例如insert(int k,T t),我们可以看做k是t关联的整数&#xff0c;那么我们的实现需要通过k这个值&#xff0c;快速获取到队列中t这个元素&a…

加速科技ST2500 数模混合信号测试设备累计装机量突破500台!

国产数字机&#xff0c;测试中国芯&#xff01;新年伊始&#xff0c;国产半导体测试设备领军企业加速科技迎来了振奋人心的一刻&#xff0c;ST2500 数模混合信号测试设备累计装机量突破500台&#xff01;加速科技凭借其持续的创新能力、完善的解决方案能力、专业热忱的本地化服…