【二分查找】LeetCode:2354.优质数对的数目

作者推荐

贪心算法LeetCode2071:你可以安排的最多任务数目

本文涉及的基础知识点

二分查找算法合集

题目

给你一个下标从 0 开始的正整数数组 nums 和一个正整数 k 。
如果满足下述条件,则数对 (num1, num2) 是 优质数对 :
num1 和 num2 都 在数组 nums 中存在。
num1 OR num2 和 num1 AND num2 的二进制表示中值为 1 的位数之和大于等于 k ,其中 OR 是按位 或 操作,而 AND 是按位 与 操作。
返回 不同 优质数对的数目。
如果 a != c 或者 b != d ,则认为 (a, b) 和 (c, d) 是不同的两个数对。例如,(1, 2) 和 (2, 1) 不同。
注意:如果 num1 在数组中至少出现 一次 ,则满足 num1 == num2 的数对 (num1, num2) 也可以是优质数对。
示例 1:
输入:nums = [1,2,3,1], k = 3
输出:5
解释:有如下几个优质数对:

  • (3, 3):(3 AND 3) 和 (3 OR 3) 的二进制表示都等于 (11) 。值为 1 的位数和等于 2 + 2 = 4 ,大于等于 k = 3 。
  • (2, 3) 和 (3, 2): (2 AND 3) 的二进制表示等于 (10) ,(2 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
  • (1, 3) 和 (3, 1): (1 AND 3) 的二进制表示等于 (01) ,(1 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
    所以优质数对的数目是 5 。
    示例 2:
    输入:nums = [5,1,1], k = 10
    输出:0
    解释:该数组中不存在优质数对。
    参数范围
    1 <= nums.length <= 105
    1 <= nums[i] <= 109
    1 <= k <= 60

分析

时间复杂度

O(nlogn),枚举数对的第二个数,时间复杂度O(n);二分查找第一个数的数量,O(logn)。

原理

如果有重复的数,删除。假定存在b1等于b2,那么任意数对(a,b1)是优质数对,则(a,b2)也是优质数对,故可以删除b1。
c=a&b d = c|b 。c和d 二进制1的数量之和,就是a和b 二进制1的数量之和
去重后,对于任意b, (x,b)都不会重复,因为x不会相等。setNum中的任意数,都可以是x,包括自己。
我们只关心a和b中1的数量,不关心a和b的值。所以枚举vBitCount。

代码

核心代码

//通过 x &= (x-1)实现
int bitcount(unsigned x) {
int countx = 0;
while (x) {
countx++;
x &= (x - 1);
}
return countx;
}

int bitcount(unsigned long long x) {
int countx = 0;
while (x) {
countx++;
x &= (x - 1);
}
return countx;
}

class Solution {
public:
	long long countExcellentPairs(vector<int>& nums, int k) {
		std::unordered_set<int> setNum(nums.begin(), nums.end());
		vector<int> vBitCount;
		for (const auto& n : setNum)
		{
			vBitCount.emplace_back(bitcount((unsigned long long)n));
		}
		sort(vBitCount.begin(), vBitCount.end());
		long long llRet = 0;
		for (const auto& n : vBitCount)
		{
			llRet += vBitCount.end() - std::lower_bound(vBitCount.begin(), vBitCount.end(), k - n);
		}
		return llRet;
	}
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

int main()
{
vector nums;
int k;
long long res;
{
Solution slu;
nums = { 1, 2, 3, 1 }, k = 3;
auto res = slu.countExcellentPairs(nums, k);
Assert(5LL, res);
}
{
Solution slu;
nums = { 5,1,1 }, k = 10;
auto res = slu.countExcellentPairs(nums, k);
Assert(0LL, res);
}
//CConsole::Out(res);
}

2023年3月版

//通过 x &= (x-1)实现
int bitcount(unsigned x) {
int countx = 0;
while (x) {
countx++;
x &= (x - 1);
}
return countx;
}

class Solution {
public:
long long countExcellentPairs(vector& nums, int k) {
std::sort(nums.begin(), nums.end());
nums.erase(std::unique(nums.begin(), nums.end()), nums.end());
std::vector vOneBitNums;
for (const auto& n : nums)
{
vOneBitNums.push_back(bitcount(n));
}
std::sort(vOneBitNums.begin(), vOneBitNums.end());
int iSameNum = vOneBitNums.end() - std::lower_bound(vOneBitNums.begin(), vOneBitNums.end(), (k + 1) / 2);
long long iNotSameNum = 0;
for (int i = 0; i < vOneBitNums.size(); i++)
{
auto itEnd = vOneBitNums.begin() + i;
iNotSameNum += itEnd - std::lower_bound(vOneBitNums.begin(), itEnd, k - vOneBitNums[i]);
}
return iSameNum + iNotSameNum * 2;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业

。也就是我们常说的专业的人做专业的事。 |
|如果程序是一条龙,那算法就是他的是睛|

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境:

VS2022 C++17

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

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

相关文章

VisualStudio反汇编功能使用

VisualStudio反汇编功能使用 使用方法 到达断点时&#xff1a;CtrlK&#xff08;松开&#xff09;G&#xff08;后按&#xff09;唤出反汇编界面&#xff0c;就可以看到当前代码对应的汇编语言了 注意&#xff1a;进入反汇编窗口后可以F10单次调试一条汇编指令 其他&#…

【vscode写vue代码是白色怎么办】

【vscode写vue代码是白色怎么办】 在插件列表中搜索Vetur 安装即可

linux虚拟机Virtualbox的下载安装及vagrant镜像下载安装

Virtualbox下载安装以及创建及简单使用一个虚拟机 1.开启电脑cpu虚拟机 以戴尔G3为例 找到电脑设置–>更新与安全–>恢复 这个步骤也可以在电脑开机时一直按键esc(或者F1、或者F2、或者deleete)都可以进入BIOS 进入BIOS 完成以上步骤就可以开启电脑cpu虚拟机了 …

使用Tomcat部署静态项目并处理BUG

--听讲的习惯 Tomcat介绍 tomcat what_Arenaschi的博客-CSDN博客 Tomcat安装及配置教程&#xff08;超详细&#xff09; 那些年我们用过的tomcat_Arenaschi的博客-CSDN博客 简单使用tomcat查看版本信息等_windows查看tomcat版本命令-CSDN博客 Tomcat部署html静态网站的五种方…

红海云eHR 任意文件上传漏洞复现

0x01 产品简介 红海eHR是大中型企业广泛采用人力资源管理系统。红海云是国内顶尖的HR软件供应商,是新一代eHR系统的领导者。 0x02 漏洞概述 红海云EHR系统PtFjk.mob接口处存在未授权文件上传漏洞,攻击者可上传webshell来命令执行,获取服务器权限。 0x03 复现环境 FOFA:…

Leetcode 17 电话号码的字母组合

理解题意&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合 本质上&#xff1a;数字代表着一个字母集合 数字的个数决定了递归的深度&#xff0c;即树的深度 数字代表的字母组合决定了当前树的宽度。 1.暴力回溯 这里没有什么剪枝…

拆解大语言模型 RLHF 中的PPO算法

为什么大多数介绍大语言模型 RLHF 的文章&#xff0c;一讲到 PPO 算法的细节就戛然而止了呢&#xff1f;要么直接略过&#xff0c;要么就只扔出一个 PPO 的链接。然而 LLM x PPO 跟传统的 PPO 还是有些不同的呀。 其实在 ChatGPT 推出后的相当一段时间内&#xff0c;我一直在等…

【数据结构】顺序表的定义和运算

目录 1.初始化 2.插入 3.删除 4.查找 5.修改 6.长度 7.遍历 8.完整代码 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &…

SpringBoot+线程池实现高频调用http接口并多线程解析json数据

场景 SpringbootFastJson实现解析第三方http接口json数据为实体类(时间格式化转换、字段包含中文)&#xff1a; SpringbootFastJson实现解析第三方http接口json数据为实体类(时间格式化转换、字段包含中文)-CSDN博客 Java中ExecutorService线程池的使用(Runnable和Callable多…

swiftUi——颜色

在SwiftUI中&#xff0c;您可以使用Color结构来表示颜色。Color可以直接使用预定义的颜色&#xff0c;例如.red、.blue、.green等&#xff0c;也可以使用自定义的RGB值、十六进制颜色代码或者系统提供的颜色。 1. 预定义颜色 Text("预定义颜色").foregroundColor(.…

使用STM32 HAL库进行GPIO控制的实例

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

人工智能学习9(LightGBM)

编译工具&#xff1a;PyCharm 文章目录 编译工具&#xff1a;PyCharm lightGBM原理lightGBM的基础使用案例1&#xff1a;鸢尾花案例2&#xff1a;绝对求生玩家排名预测一、数据处理部分1.数据获取及分析2.缺失数据处理3.数据规范化4.规范化输出部分数据5.异常数据处理5.1删除开…

调用win32 api获取电脑名字和系统目录

学习一下几个函数的功能&#xff0c;和调用方式&#xff1b; void CBasenameView::OnDraw(CDC* pDC) {CBasenameDoc* pDoc GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCString str1;TCHAR myname1[50], myname2[50], mydirname1[50], myd…

class061 最小生成树【算法】

class061 最小生成树【算法】 2023-12-8 11:48:12 算法讲解061【必备】最小生成树 code1 P3366 【模板】最小生成树 // Kruskal算法模版&#xff08;洛谷&#xff09; // 静态空间实现 // 测试链接 : https://www.luogu.com.cn/problem/P3366 // 请同学们务必参考如下代码中…

实战:Docker Compose 下 Nginx、Java、Mysql 和 Redis 服务协同部署(包含解决浏览器访问Linux部署服务器本地资源问题)

1. 背景 在该实战中&#xff0c;我们将探讨如何使用Docker Compose协同部署Nginx、Java、Mysql和Redis服务&#xff0c;实现一个视频上传与展示的应用。具体需求如下&#xff1a; Java应用负责上传视频和图片资源到Nginx目录下&#xff0c;作为资源服务器。Nginx服务作为静态…

Redis数据已经删除了,为什么内存占用还是很高?

Redis数据已经删除了&#xff0c;为什么内存占用还是很高&#xff1f; Redis做了数据删除操作&#xff0c;为什么使用top命令时&#xff0c;还是显示Redis占了很多内存&#xff1f; 没做相关功课的人觉得这个问题有问题&#xff0c;删了数据还说占着内存&#xff0c;面试官不…

ubuntu22.04 安装cuda

CUDA&#xff08;Compute Unified Device Architecture&#xff09;是由 NVIDIA 开发的一种并行计算平台和编程模型。它允许开发者利用 NVIDIA 的 GPU&#xff08;图形处理单元&#xff09;进行高效的计算处理。CUDA 通过提供一系列的 C、C 和 Fortran 扩展&#xff0c;使得开发…

Navicat 技术指引 | 连接 GaussDB 分布式

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…

小程序开发要多少钱

随着智能手机的普及和人们对移动应用的需求不断增长&#xff0c;小程序作为一种轻量级应用形式&#xff0c;在商业领域中备受关注。众多企业都渴望抓住这一机遇&#xff0c;但他们最关心的问题之一是&#xff1a;小程序开发需要多少钱&#xff1f; 一、开发方式选择 在开始小…

【LuatOS】笔记(二)基础框架

开发环境搭建 合宙官方搭建的是&#xff1a;vscodeLuatOS-SOC推荐拓展包(vscode插件)&#xff0c;原文链接&#xff1a;LuatOS开发环境搭建。安装完创建项目文件&#xff0c;创建main.lua文件&#xff0c;就可以开始编写了。 函数与使用 LuatOS-SOC接口文档1&#xff0c;该文档…
最新文章