力扣双周赛第三题----2857. 统计距离为 k 的点对

 这题我们的暴力做法就是o(n^2),但是根据数据量这样会超时,所以我们不能用暴力解法去解决

那么想一想双指针可以吗,不可以。为什么呢?因为他没有一个特性可以让他双指针跳过前面或者后面一个点。比如他们数组有顺序的情况下,还有一种性质,这个我也不知道怎么说,就是有个性质满足才能双指针,当前题目不能满足的话,那么我们就只能针对异或这个性质入手了,并且他的k的数只有100,那么只有100,那么其实就可以用k和异或这个性质同时入手

//异或的运算法则

假设x1^x2 = i,y1^y2 = (k - i),这样 x1^x2 + y1^y2 = k,根据运算法则得出

x1^x2^x2 = i^x2,y1^y2^y2 = (k - i)^y2

得出x1 = i^x2,y1 = (k - 2)^y2,我们的k和i是可以已知的,那么我们只要枚举i为1~k就行就可以求出

i和k-i,有了这个之后我们还是要遍历点的数组,因为我们其实是拿着点的坐标去暴力枚举i,k-i去试出来是否等于k,为什么这样可以呢?这是因为只要有一个点的坐标,然后暴力枚举出来等于k的可能性,那么枚举出等于k的数的话,我们就可以通过x1 = i^x2,y1 = (k - 2)^y2求出来x1,y1这个数了,那么我们怎么统计呢?现在外层循环是遍历点的数组,第二层循环是暴力枚举i为1~k,

那么第三层循环其实就是统计符合i < j,并且满足距离 为 (x1 XOR x2) + (y1 XOR y2) 这个

条件,我们怎么找到符合x1,y1的数呢,我们可以用哈希表进行预处理出来x1,y1的下标有哪些。

 但是我们在统计的时候我们这样还是会出现o(n)的情况,因为会从头到尾遍历x1,y1这个数的下标,统计的话是统计x1,y1这个key的所有下标有几个小于外层循环遍历的原数组的下标。

所以我们是要优化统计这部分,我们先找到一个性质,key值x1,y1里的元素是不是顺序的,肯定是递增顺序的,这个不好证明,如果想去证明可以自己去证明,但是这是个很显然的性质,只要我们预处理的时候是按照下标顺序遍历的话,那么预处理出来的key值对应的元素也一定是按照顺序进行存储的,所以有了顺序性,那么我们就可以用二分来找到大于等于外层循环的下标的最小值,

然后统计出来有几个大于外层循环的下标元素个数。

所以时间复杂度就是O(n*k*logn);是绝对能过的

C++:最好用unordered_map,我是因为这个好像有点问题就不管了

#include <map>
#include <vector>
using namespace std;

class Solution {
public:
    map<pair<int, int>, vector<int>> hashs;

    int countPairs(vector<vector<int>>& coordinates, int k) {
        int n = coordinates.size();
        int ans = 0;
        
        for (int i = 0; i < n; i++) {
            pair<int, int> key = make_pair(coordinates[i][0], coordinates[i][1]);
            hashs[key].push_back(i);
        }
        
        for (int i = 0; i < n; i++) {
            int x2 = coordinates[i][0];
            int y2 = coordinates[i][1];
            
            for (int j = 0; j <= k; j++) {
                int i1 = j;
                int ki1 = k - j;
                int x1 = (i1 ^ x2);
                int y1 = (ki1 ^ y2);
                
                auto it = hashs.find(make_pair(x1, y1));
                if (it != hashs.end()) {
                    vector<int>& a = it->second;
                    int l = 0;
                    int r = a.size() - 1;
                    
                    while (l < r) {
                        int mid = (l + r) / 2;
                        
                        if (a[mid] >= i) {
                            r = mid;
                        } else {
                            l = mid + 1;
                        }
                    }
                    
                    int find_index = 0;
                    if (a[l] < i) {
                        find_index = -1;
                    }

                    if (a[l] == i) {
                        ans += a.size() - l - 1;
                    } else if (find_index == -1) {
                        ans += 0;
                    } else {
                        ans += a.size() - l;
                    }
                }
            }
        }
        
        return ans;
    }
};
class Solution {
    public int countPairs(List<List<Integer>> coordinates, int k) {
        int n = coordinates.size();
        int ans = 0;
        Map<Pair<Integer, Integer>, List<Integer>> hashs = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int x = coordinates.get(i).get(0), y = coordinates.get(i).get(1);
            hashs.computeIfAbsent(new Pair<>(x, y), k1 -> new ArrayList<>()).add(i);
        }
        for (int i = 0; i < n; i++) {
            int x2 = coordinates.get(i).get(0), y2 = coordinates.get(i).get(1);
            for (int j = 0; j <= k; j++) {
                int i1 = j, ki1 = k - j;
                int x1 = (i1 ^ x2), y1 = (ki1 ^ y2);
                List<Integer> a = hashs.getOrDefault(new Pair<>(x1, y1), null);
                if (a != null) {
                    int l = 0, r = a.size() - 1;
                    while (l < r) {
                        int mid = (l + r) / 2;
                        if (a.get(mid) >= i) {
                            r = mid;
                        } else {
                            l = mid + 1;
                        }
                    }
                    int find_index = 0;
                    if (a.get(l) < i) {
                        find_index = -1;
                    }
                    if (a.get(l) == i) {
                        ans += a.size() - l - 1;
                    } else if (find_index == -1) {
                        ans += 0;
                    } else {
                        ans += a.size() - l;
                    }
                }
            }
        }
        return ans;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JaveWeb教程】(23) MySQL数据库开发之事务与索引 详细代码示例讲解(最全面)

目录 2. 事务2.1 介绍2.2 操作2.3 四大特性 3. 索引3.1 介绍3.2 结构3.3 语法 2. 事务 场景&#xff1a;学工部整个部门解散了&#xff0c;该部门及部门下的员工都需要删除了。 操作&#xff1a; -- 删除学工部 delete from dept where id 1; -- 删除成功-- 删除学工部的员工…

某厂校招一道关于C的笔试题

一、笔试原题 题目&#xff1a;在Linux x86 _ 54 gcc环境下&#xff0c;下面的程序会出现什么问题&#xff1f;运行结果是什么&#xff1f;为什么&#xff1f; 程序如下图&#xff1a; 通过在gcc的环境下编译运行&#xff0c;发现运行结果为不断死循环打印0-17的数字 我们…

遥感影像-语义分割数据集:高分卫星-云数据集详细介绍及训练样本处理流程

原始数据集详情 简介&#xff1a;该云数据集包括RGB三通道的高分辨率图像&#xff0c;包含高分一、高分二及宽幅数据集。 KeyValue卫星类型高分系列覆盖区域未知场景未知分辨率1m、2m、8m数量12000单张尺寸1024*1024原始影像位深8位标签图片位深8位原始影像通道数三通道标签图…

云卷云舒:AI for DB、DB for AI

云卷云舒&#xff1a;算力网络云原生&#xff08;下&#xff09;&#xff1a;云数据库发展的新篇章-CSDN博客https://blog.csdn.net/bishenghua/article/details/135050556 随着数据库和AI技术的分支同向演进&#xff0c;AI 和数据库间的关联越发紧密了。 大模型的演进发展&a…

为何资深程序员都离不开 requirements.txt?你还在为环境配置发愁吗?

requirements.txt 文件是一个用于记录 Python 包依赖的文件&#xff0c;它能够帮助我们快速配置开发环境。在迁移到新的开发环境时&#xff0c;通常需要逐个使用 pip install 命令安装各种包&#xff0c;这个过程既耗时又可能出现错误。 而 requirements.txt 文件可以让我们一…

通过IP地址识别风险用户

随着互联网的迅猛发展&#xff0c;网络安全成为企业和个人关注的焦点之一。识别和防范潜在的风险用户是维护网络安全的关键环节之一。IP数据云将探讨通过IP地址识别风险用户的方法和意义。 IP地址的基本概念&#xff1a;IP地址是互联网上设备的独特标识符&#xff0c;它分为IP…

靶场实战(14):OSCP备考之VulnHub SUNSET NOONTIDE

打靶思路 资产发现 主机发现服务发现漏洞发现&#xff08;获取权限&#xff09; irc服务提升权限 server用户 sudosuidcron内核提权信息收集 1、资产发现 1.1、主机发现 本次靶场SUNSET: NOONTIDE[1]指定IP&#xff0c;不涉及主机发现过程。 1.2、服务发现 使用命令sudo -u roo…

Kubernetes 集群管理—日志架构

日志架构 应用日志可以让你了解应用内部的运行状况。日志对调试问题和监控集群活动非常有用。 大部分现代化应用都有某种日志记录机制。同样地&#xff0c;容器引擎也被设计成支持日志记录。 针对容器化应用&#xff0c;最简单且最广泛采用的日志记录方式就是写入标准输出和标…

调用openai实现聊天功能

&#x1f4d1;前言 本文主要是【聊天机器人】——调用openai实现聊天功能的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f3…

编译和链接(2)

3. 预处理详解 3.2#define 3.2.5带副作用的宏参数 当宏参数在宏的定义中出现超过一次的时候&#xff0c;如果参数带有副作用&#xff0c;那么你在使用这个宏的时候就可能 出现危险&#xff0c;导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。 例如&…

day16 二叉树的最大深度 n叉树的最大深度 二叉树的最小深度 完全二叉树的节点数

题目1&#xff1a;104 二叉树的最大深度 题目链接&#xff1a;104 二叉树的最大深度 题意 二叉树的根节点是root&#xff0c;返回其最大深度&#xff08;从根节点到最远叶子节点的最长路径上的节点数&#xff09; 递归 根节点的的高度就是二叉树的最大深度 所以使用后序遍…

【Minio】常见问题解决思路

检查存储服务器对应的端口与应用服务器是否能够互通&#xff0c;通过ping|telnet命令检查、查看防火墙端口是否开放&#xff0c;检查防火墙端口linux系统和windows系统各有不同。检查电脑上的杀毒软件是否限制了网络端口和文件权限问题。检查minio配置信息是否正确&#xff0c;…

Unity AssetBundles资源管理和热更新

项目中的做法&#xff0c;在项目中一般会把资源按照文件目录去划分资源&#xff0c;以文件路径的名字作为AB的名字&#xff0c;一般都是把资源的这些放到预处理中。 一般会分为几个类型&#xff0c;比如把单个文件夹下的每个资源进行打bundle&#xff0c;把单个文件夹下的所有资…

10年果粉拯救老掉牙Mac心得(没错我是标题党)

连续两周了&#xff0c;当我不能用Mac,或者说当我闲置了近10年隔三差五的用Mac时&#xff0c;成功发现我的AppleID已经无法登录了。事情是这样的&#xff0c;当我踌躇满志地准备改一篇稿子&#xff08;潜在的稿费啊亲&#xff01;&#xff09;时&#xff0c;发现Pages竟然没有W…

驾驭数字孪生:智慧水利的未来之路

一、数字孪生技术的原理与实践 随着科技的不断进步&#xff0c;数字孪生技术作为一项创新的技术应用&#xff0c;正在逐渐改变我们的生活和工作方式。特别是在工业领域&#xff0c;数字孪生技术被视为实现智能制造、提升生产效率和产品质量的重要手段。本章节将深入探讨数字孪…

Docker 安装:在linux系统CentOS7 版本 安装Docker

目录 一&#xff0c;Docker介绍&#xff1a; 1.1Docker是什么&#xff1f; 1.2Docker组成 二&#xff0c;Docker安装&#xff1a; 三&#xff0c;Docker基本使用 3.1服务 3.2镜像 3.3容器 &#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&am…

VMware workstation搭建与安装AnolisOS-8.8虚拟机

VMware workstation搭建与安装AnolisOS-8.8虚拟机 适用于需要在VMware workstation平台安装AnolisOS-8.8&#xff08;最小化安装、无图形化界面&#xff09;虚拟机。 1. 安装准备 1.1 安装平台 Windows 11 1.2. 软件信息 软件名称软件版本安装路径VMware-workstation 17 …

前端js调用Lodop实现云打印

一、下载Lodop控件 官网&#xff1a;下载中心 - Lodop和C-Lodop官网主站 二、解压后安装 双击进行安装&#xff0c;里面有些页面文件是一些教程案例 勾选云服务工作模式 安装成功会自动启动 浏览器访问地址&#xff1a;http://localhost:8000/ 首页最下面有个教程案例跳转地址&…

【已解决】C语言实现多线程的同步与异步

说真的写了这篇博文时&#xff0c;才知道c语言本身不支持多线程&#xff0c;而是一些windowsapi让c语言拥有多线程的能力&#xff0c;那下面内容就以打开对话框为例&#xff0c;展现如何实现多线程的同步与异步。 文章目录 问题起源c语言多线程同步方案c语言多线程异步方案总结…

Raspbian安装摄像头

Raspbian安装摄像头 1. 源由2. 摄像头2.1 选型2.2 系统2.3 安装 3. 配置&命令3.1 命令3.2 配置 4. 测试4.1 拍照4.1.1 libcamera-jpeg4.1.2 libcamera-still 4.2 视频流4.2.1 RTSP流4.2.2 TCP流 5. 参考资料 1. 源由 家里闲置两块树莓派&#xff0c;打算做个WiFi视频流RTS…