[二分查找]LeetCode2040:两个有序数组的第 K 小乘积

news2025/2/27 2:49:09

本文涉及的基础知识点

二分查找算法合集

题目

给你两个 从小到大排好序 且下标从 0 开始的整数数组 nums1 和 nums2 以及一个整数 k ,请你返回第 k (从 1 开始编号)小的 nums1[i] * nums2[j] 的乘积,其中 0 <= i < nums1.length 且 0 <= j < nums2.length 。
示例 1:
输入:nums1 = [2,5], nums2 = [3,4], k = 2
输出:8
解释:第 2 小的乘积计算如下:

  • nums1[0] * nums2[0] = 2 * 3 = 6
  • nums1[0] * nums2[1] = 2 * 4 = 8
    第 2 小的乘积为 8 。
    示例 2:
    输入:nums1 = [-4,-2,0,3], nums2 = [2,4], k = 6
    输出:0
    解释:第 6 小的乘积计算如下:
  • nums1[0] * nums2[1] = (-4) * 4 = -16
  • nums1[0] * nums2[0] = (-4) * 2 = -8
  • nums1[1] * nums2[1] = (-2) * 4 = -8
  • nums1[1] * nums2[0] = (-2) * 2 = -4
  • nums1[2] * nums2[0] = 0 * 2 = 0
  • nums1[2] * nums2[1] = 0 * 4 = 0
    第 6 小的乘积为 0 。
    示例 3:
    输入:nums1 = [-2,-1,0,1,2], nums2 = [-3,-1,2,4,5], k = 3
    输出:-6
    解释:第 3 小的乘积计算如下:
  • nums1[0] * nums2[4] = (-2) * 5 = -10
  • nums1[0] * nums2[3] = (-2) * 4 = -8
  • nums1[4] * nums2[0] = 2 * (-3) = -6
    第 3 小的乘积为 -6 。
    参数范围
    1 <= nums1.length, nums2.length <= 5 * 104
    -105 <= nums1[i], nums2[j] <= 105
    1 <= k <= nums1.length * nums2.length
    nums1 和 nums2 都是从小到大排好序的。

两层二分查找

时间复杂度

O(log(max2)nlogn),n是两个数组长度的较大者,max 是两个数组的最大值。

分情况讨论

结果数组一数组二
负数负数正数
负数正数负数
00任意数
0非00
正数正数正数
正数负数负数

第一层二分

寻找一个符合如下条件的llMul:
乘积小于等于llMul的组合数量大于等于k。
左开右闭空间。

负数的问题

如果乘积为负数,第k小则绝对值第k大。我们可以负数全部转成绝对值,然后倒序,这样可以保证升序。m个数,第k大(从1开始),就是m-k+1小。

变量解释

v11数组一中的负数的绝对值,升序
v12数组一中的正数,升序
v21数组二中的负数的绝对值,升序
v22数组二中的正数,升序

代码

核心代码

class Solution {
public:
long long kthSmallestProduct(vector& nums1, vector& nums2, long long k) {
auto it1 = std::equal_range(nums1.begin(), nums1.end(), 0);
auto it2 = std::equal_range(nums2.begin(), nums2.end(), 0);
const long long less0Count1 = it1.first - nums1.begin();
const long long i0Count1 = it1.second - it1.first;
const long long great0Count1 = nums1.end() - it1.second;
const long long less0Count2 = it2.first - nums2.begin();
const long long i0Count2 = it2.second - it2.first;
const long long great0Count2 = nums2.end() - it2.second;
const long long llZeroCount = i0Count1 * nums2.size() + i0Count2 * nums1.size() - i0Count1 * i0Count2;
const long long llLess0Cout = less0Count1 * great0Count2 + less0Count2 * great0Count1;
vector v12(it1.second, nums1.end());
vector v22(it2.second, nums2.end());
vector v11 = CopyAndMul(vector(nums1.begin(), it1.first));
vector v21 = CopyAndMul(vector(nums2.begin(), it2.first));
if (k <= llLess0Cout)
{//在负数中找
k = llLess0Cout + 1 - k;
return -DoGreate0(v11, v22, v21, v12, k);
}
k -= llLess0Cout;
if (k <= llZeroCount)
{
return 0;
}
k -= llZeroCount;
return DoGreate0(v11, v21,v12, v22,k);
}
//从升序正数数组中寻找第k小的积: 第一个积小于等于llMul 的数量大于等于k 左开右闭
long long DoGreate0(const vector& nums11,const vector& nums12, const vector& nums21, const vector& nums22, long long k)
{
long long left = 0, right = (long long) 1e10;
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
int iCnt = 0;
const long long llHas = LessEqual(nums11, nums12, mid) + LessEqual(nums21, nums22, mid);
if (llHas >= k)
{
right = mid;
}
else
{
left = mid;
}
}
return right;
}
long long LessEqual(const vector& nums1, const vector& nums2, long long llMul)
{
long long llCnt = 0;
for (const auto& n : nums2)
{
llCnt += std::upper_bound(nums1.begin(), nums1.end(), llMul / n) - nums1.begin();
}
return llCnt;
}
vector CopyAndMul(const vector& nums)
{
vector vRet(nums.size());
for (int i = 0; i < nums.size(); i++)
{
vRet[i] = -nums[nums.size() - 1 - i];
}
return vRet;
}
};

测试用例

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 nums1, nums2;
long long k, res;
{
nums1 = { -2,-1 }, nums2 = { -2,-1 }, k = 4;
Solution slu;
auto res = slu.kthSmallestProduct(nums1, nums2, k);
Assert(4LL, res);
}
{
nums1 = { 2, 5 }, nums2 = { 3, 4 }, k = 2;
Solution slu;
auto res = slu.kthSmallestProduct(nums1, nums2, k);
Assert(8LL, res);
}
{
nums1 = { -4,-2,0,3 }, nums2 = { 2,4 }, k = 6;
Solution slu;
auto res = slu.kthSmallestProduct(nums1, nums2, k);
Assert(0LL, res);
}
{
nums1 = { -2,-1,0,1,2 }, nums2 = { -3,-1,2,4,5 }, k = 3;
Solution slu;
auto res = slu.kthSmallestProduct(nums1, nums2, k);
Assert(-6LL, res);
}
{
nums1 = { 0 }, nums2 = { 0,0,0}, k = 3;
Solution slu;
auto res = slu.kthSmallestProduct(nums1, nums2, k);
Assert(0LL, res);
}
{
nums1 = { 1,2 }, nums2 = { 1,2}, k = 3;
Solution slu;
auto res = slu.kthSmallestProduct(nums1, nums2, k);
Assert(2LL, res);
}
{
nums1 = { 1,10000 };
nums2 = { 1,10000 };
k = 4;
Solution slu;
auto res = slu.kthSmallestProduct(nums1, nums2, k);
Assert(10000* 10000LL, res);
}

//CConsole::Out(res);

}

优化一

确保数组二的长度比数组一短

if (nums1.size() < nums2.size())
		{
			swap(nums1, nums2);
		}

完整函数:

	long long LessEqual( vector<int>& nums1,  vector<int>& nums2, long long llMul)
	{
		if (nums1.size() < nums2.size())
		{
			swap(nums1, nums2);
		}
		long long llCnt = 0;
		for (const auto& n : nums2)
		{
			llCnt += std::upper_bound(nums1.begin(), nums1.end(), llMul / n) - nums1.begin();
		}
		return llCnt;
	}

优化二

第二层二分查找可以优化成双指针。这样也不用思考取整之类,容易理解。

	long long LessEqual( vector<int>& nums1,  vector<int>& nums2, long long llMul)
	{
		long long llCnt = 0;
		int right = nums1.size()-1;
		for (const auto& n : nums2)
		{
			while ((right >=0 ) && (nums1[right] * (long long)n > llMul))
			{//nums1[0,right]*n 全部小于等于llMul
				right--;
			}
			llCnt += (right+1);
		}
		return llCnt;
	}

优化三

0不必单独考虑。0符合负数的规则:绝对值越大,乘积越小。0也符合正数的规则,觉得值越大,乘积越大。

class Solution {
public:
	long long kthSmallestProduct(vector<int>& nums1, vector<int>& nums2, long long k) {
		auto it1 = std::lower_bound(nums1.begin(), nums1.end(), 0);
		auto it2 = std::lower_bound(nums2.begin(), nums2.end(), 0);
		vector<int> v12(it1, nums1.end());
		vector<int> v22(it2, nums2.end());
		vector<int> v11 = CopyAndMul(vector<int>(nums1.begin(), it1));
		vector<int> v21 = CopyAndMul(vector<int>(nums2.begin(), it2));
		const long long ll24Count = v11.size() * (long long)v22.size() + (long long)v12.size() * v21.size();
		if (k <= ll24Count)
		{//在负数中找
			k = ll24Count + 1 - k;
			return -DoGreate0(v11, v22, v21, v12, k);
		}
		k -= ll24Count;	
		return DoGreate0(v11, v21,v12, v22,k);
	}
	//从升序正数数组中寻找第k小的积: 第一个积小于等于llMul 的数量大于等于k 左开右闭
	long long DoGreate0( vector<int>& nums11, vector<int>& nums12,  vector<int>& nums21,  vector<int>& nums22, long long k)
	{
		long long left = -1, right = (long long) 1e10;
		while (right - left > 1)
		{
			const auto mid = left + (right - left) / 2;
			const long long llHas = LessEqual(nums11, nums12, mid) + LessEqual(nums21, nums22, mid);
			if (llHas >= k)
			{
				right = mid;
			}
			else
			{
				left = mid;
			}
		}
		return right;
	}
	long long LessEqual( vector<int>& nums1,  vector<int>& nums2, long long llMul)
	{
		long long llCnt = 0;
		int right = nums1.size()-1;
		for (const auto& n : nums2)
		{
			while ((right >=0 ) && (nums1[right] * (long long)n > llMul))
			{//nums1[0,right]*n 全部小于等于llMul
				right--;
			}
			llCnt += (right+1);
		}
		return llCnt;
	}
	vector<int> CopyAndMul(const vector<int>& nums)
	{
		vector<int> vRet(nums.size());
		for (int i = 0; i < nums.size(); i++)
		{
			vRet[i] = -nums[nums.size() - 1 - i];
		}
		return vRet;
	}
};

2023年3月版

class CNumHelp
{
public:
CNumHelp(vector& nums) :m_nums(nums)
{
auto it1 = std::equal_range(m_nums.begin(), m_nums.end(), 0);
m_iLess0Num = it1.first - m_nums.begin();
m_i0Num = it1.second - it1.first;
m_iMore0Num = m_nums.end() - it1.second;
m_iLessEqual0Num = m_iLess0Num + m_i0Num;
m_iMoreEqualNum = m_iMore0Num + m_i0Num;
}
vector m_nums;
int m_iLess0Num = 0, m_i0Num = 0, m_iMore0Num = 0;
int m_iLessEqual0Num = 0,m_iMoreEqualNum=0;
};

class ICal
{
public:
virtual long long Cal(long long llMid)const = 0;
};
class CCalMore0 : public ICal
{
public:
CCalMore0(const CNumHelp& help1, const CNumHelp& help2) :m_help1(help1), m_help2(help2)
{

 }
 virtual long long Cal(long long llMid)const
 {
	 long long llNum = 0;
	 for (int i = m_help1.m_iLessEqual0Num; i < m_help1.m_nums.size(); i++)
	 {
		 int iCurNum = std::upper_bound(m_help2.m_nums.begin(), m_help2.m_nums.end(), llMid / m_help1.m_nums[i]) - m_help2.m_nums.begin() - m_help2.m_iLessEqual0Num;
		 llNum += iCurNum;
	 }

	 for (int i = 0; i < m_help1.m_iLess0Num; i++)
	 {
		 auto it = std::equal_range(m_help2.m_nums.begin(), m_help2.m_nums.end(), llMid / m_help1.m_nums[i]);
		 //auto it2 = (0 == llMid % m_help1.m_nums[i]) ? it.first : it.second;
		 auto it2 = it.first;
		 llNum += m_help2.m_nums.end() - it2 - m_help2.m_iMoreEqualNum;
	 }
	 return llNum;
 }

private:

 const CNumHelp m_help1;
 const CNumHelp m_help2;

};

class CCalLess0 : public ICal
{
public:
CCalLess0(const CNumHelp& help1, const CNumHelp& help2) :m_help1(help1), m_help2(help2)
{
}
virtual long long Cal(long long llMid)const
{
return Cal(llMid, m_help1, m_help2) + Cal(llMid, m_help2, m_help1);
}
static long long Cal(long long llMid, const CNumHelp& help1, const CNumHelp& help2)
{
long long llNum = 0;
for (int i = help1.m_iLessEqual0Num; i < help1.m_nums.size(); i++)
{
auto it = std::equal_range(help2.m_nums.begin(), help2.m_nums.end(), llMid / help1.m_nums[i]);
auto it2 = (0 == llMid% help1.m_nums[i]) ? it.second : it.first;
int iCurNum = it2 -help2.m_nums.begin();
llNum += iCurNum;
}
return llNum;
}
private:
const CNumHelp m_help1;
const CNumHelp m_help2;
};
class Solution {
public:
long long kthSmallestProduct(vector& nums1, vector& nums2, long long k) {
CNumHelp help1(nums1), help2(nums2);
//const long long llTotal = (long long)nums1.size()nums2.size();
const long long ll0Num = (long long)help1.m_i0Num * nums2.size() + (long long)help2.m_i0Num * nums1.size() - (long long)help1.m_i0Num
help2.m_i0Num;
const long long llLess0Num = (long long)help1.m_iMore0Num * help2.m_iLess0Num + (long long)help1.m_iLess0Num * help2.m_iMore0Num;
if (k <= llLess0Num)
{
CCalLess0 cal(help1, help2);
return Do(cal, k, (long long)100000 * -100000 - 1,-1);
}
k -= llLess0Num;
if (k <= ll0Num)
{
return 0;
}
k -= ll0Num;
CCalMore0 cal(help1, help2);
return Do(cal, k, 0, (long long)100000 * 100000);
}
long long Do(const ICal& cal, long long k, long long left, long right)
{
while (right > left + 1)
{
const auto llMid = left + (right - left) / 2;
const long long llNum = cal.Cal(llMid);
if (llNum >= k)
{
right = llMid;
}
else
{
left = llMid;
}
}
return right;
}

};

2023年9月

class Solution {
public:
long long kthSmallestProduct(const vector& nums1, const vector& nums2, long long k) {
CalRange(nums1, m_v11, m_v12);
CalRange(nums2, m_v21, m_v22);
const int iZero1Num = nums1.size() - m_v11.size() - m_v12.size();
const int iZero2Num = nums2.size() - m_v21.size() - m_v22.size();
long long llLess0 = (long long)m_v11.size() * m_v22.size() + (long long)m_v21.size() * m_v12.size();
long long ll0 = (long long)nums2.size() * iZero1Num + (long long)nums1.size() * iZero2Num - (long long)iZero1Num * iZero2Num;
if (k <= llLess0)
{//结果是负数
m_v21.swap(m_v22);
return -Do(llLess0 - k + 1);
}
k -= llLess0;
if (k <= ll0)
{
return 0;
}
k -= ll0;
return Do(k);
}
long long Do(long long k)
{
long long left =-(1e10 + 0.5)-1, r = 1e10 + 0.5;
while (r - left > 1)
{
const auto mid = left + (r - left) / 2;
long long llNum = CountEqualLess(m_v11, m_v21,mid) + CountEqualLess(m_v12, m_v22,mid);
if (llNum >= k)
{
r = mid;
}
else
{
left = mid;
}
}
return r;
}
long long CountEqualLess(const vector& nums1, const vector& nums2, long long llMul)
{
long long llCnt = 0;
int r = 0 ;//[0,r)和num2[i]的乘积 < llMul
for (int i =nums2.size()-1; i >= 0 ;i-- )
{
for (; (r < nums1.size() ) && ((long long)nums1[r] * nums2[i] <= llMul); r++);
llCnt += r;
}
return llCnt;
}
static void CalRange(const vector& nums, vector& v1, vector& v2)
{
int i = 0;
for (i = 0; (i < nums.size()) && (nums[i] < 0); i++)
{
v1.emplace_back(-nums[i]);
}
std::reverse(v1.begin(), v1.end());
for (; (i < nums.size()) && (nums[i] == 0); i++);
for (; i < nums.size(); i++)
{
v2.emplace_back(nums[i]);
}
}
vector m_v11, m_v12, m_v21, m_v22;

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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.coloradmin.cn/o/1281724.html

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

相关文章

45 - 多线程性能优化常见问题

1、使用系统命令查看上下文切换 上下文切换常见的监测工具 1.1、Linux 命令行工具之 vmstat 命令 vmstat 是一款指定采样周期和次数的功能性监测工具&#xff0c;我们可以使用它监控进程上下文切换的情况。 vmstat 1 3 命令行代表每秒收集一次性能指标&#xff0c;总共获取 …

代码随想录算法训练营 ---第五十三天

第一题&#xff1a; 简介&#xff1a; 本题和昨天的最大重复子串问题很相似&#xff0c;只不过本题不一定是连续的。 动规五部曲分析如下&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j]&#xff1a;长度为i-1 的字符串text1与长度为j-1的…

智能优化算法应用:基于供需算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于供需算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于供需算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.供需算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

YoloV8改进策略:Swift Parameter-free Attention,无参注意力机制,超分模型的完美迁移

摘要 https://arxiv.org/pdf/2311.12770.pdf https://github.com/hongyuanyu/SPAN SPAN是一种超分网络模型。SPAN模型通过使用参数自由的注意力机制来提高SISR的性能。这种注意力机制能够增强重要信息并减少冗余,从而在图像超分辨率过程中提高图像质量。 具体来说,SPAN模…

Java三种代理模式:静态代理、动态代理和CGLIB代理

Java三种代理模式&#xff1a;静态代理、动态代理和CGLIB代理 代理模式 代理模式是23种设计模式种的一种。代理模式是一种结构型设计模式&#xff0c;它允许为其他对象提供一个替代品或占位符&#xff0c;以控制对这个对象的访问。代理模式可以在不修改被代理对象的基础上&am…

JavaScript基础知识20——循环结构:退出循环

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 最近一段时间没学习JavaScript&#xff0c;今天看数字孪生的资料&#xff0c;发现很多低代码开发还是得必须熟悉JavaScript才行&#xff0c;为了以后方便搞数字孪生&#xff0c;有时间还是继续学习下JavaScript。 以下…

矩阵元素求和:按行、按列、所有元素np.einsum()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 矩阵元素求和&#xff1a; 按行、按列、所有元素 np.einsum() [太阳]选择题 下列说法正确的是&#xff1a; import numpy as np A np.array([[1, 2],[3, 4]]) print("【显示】A") p…

HR看好的字符函数和字符串处理函数!!!

本篇会加入个人的所谓‘鱼式疯言’❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言,而是理解过并总结出来通俗易懂的大白话,我会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的&#xff0c;可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 前言 在本篇…

【Google2023】利用TiDE进行长期预测实战(时间序列密集编码器)

一、本文介绍 大家好&#xff0c;最近在搞论文所以在研究各种论文的思想&#xff0c;这篇文章给大家带来的是TiDE模型由Goggle在2023.8年发布&#xff0c;其主要的核心思想是&#xff1a;基于多层感知机&#xff08;MLP&#xff09;构建的编码器-解码器架构&#xff0c;核心创…

【设计模式-4.3】行为型——责任链模式

说明&#xff1a;本文介绍设计模式中行为型设计模式中的&#xff0c;责任链模式&#xff1b; 审批流程 责任链模式属于行为型设计模式&#xff0c;关注于对象的行为。责任链模式非常典型的案例&#xff0c;就是审批流程的实现。如一个报销单的审批流程&#xff0c;根据报销单…

44 - 几款常用的性能测试工具

熟练掌握一款性能测试工具&#xff0c;是我们必备的一项技能。他不仅可以帮助我们模拟测试场景&#xff08;包括并发、复杂的组合场景&#xff09;&#xff0c;还能将测试结果转化成数据或图形&#xff0c;帮助我们更直观地了解系统性能。 1、常用的性能测试工具 常用的性能测…

前端笔记(二):CSS 选择器与特性

CSS&#xff08;层叠样式表&#xff09;是一种样式表语言&#xff0c;用于描述HTML或XML文档的呈现方式。它定义了如何在屏幕、纸张或其他媒体上显示文档的样式、布局和外观。 里面的代码由 选择器 { } 组成 体验 CSS CSS 可以让我们界面变得更加美观&#xff0c;这是 CSS 的…

Kafka 架构深度解析:生产者(Producer)和消费者(Consumer)

Apache Kafka 作为分布式流处理平台&#xff0c;其架构中的生产者和消费者是核心组件&#xff0c;负责实现高效的消息生产和消费。本文将深入剖析 Kafka 架构中生产者和消费者的工作原理、核心概念以及高级功能。 Kafka 生产者&#xff08;Producer&#xff09; 1 发送消息到…

RPG项目01_脚本代码

基于“RPG项目01_场景及人物动画管理器”&#xff0c;我们创建一个XML文档 在资源文件夹下创建一个文件夹&#xff0c; 命名为Xml 将Xnl文档拖拽至文件夹中&#xff0c; 再在文件夹的Manager下新建脚本LoadManager 写代码&#xff1a; using System.Collections; using System…

基于CNN对彩色图像数据集CIFAR-10实现图像分类--keras框架实现

项目地址&#xff08;kaggle&#xff09;&#xff1a;基于CNN对彩色图像数据集CIFAR-10实现图像分类--keras | Kaggle 项目地址&#xff08;Colab&#xff09;&#xff1a;https://colab.research.google.com/drive/1gjzglPBfQKuhfyT3RlltCLUPgfccT_G9 导入依赖 在tensorflow…

若依的基本使用

演示使用网址:若依管理系统 网站:RuoYi 若依官方网站 |后台管理系统|权限管理系统|快速开发框架|企业管理系统|开源框架|微服务框架|前后端分离框架|开源后台系统|RuoYi|RuoYi-Vue|RuoYi-Cloud|RuoYi框架|RuoYi开源|RuoYi视频|若依视频|RuoYi开发文档|若依开发文档|Java开源框架…

绝地求生在steam叫什么?

绝地求生在Steam的全名是《PlayerUnknowns Battlegrounds》&#xff0c;简称为PUBG。作为一款风靡全球的多人在线游戏&#xff0c;PUBG于2017年3月23日正式上线Steam平台&#xff0c;并迅速成为一部热门游戏。 PUBG以生存竞技为核心玩法&#xff0c;玩家将被投放到一个辽阔的荒…

基于 ESP32 的带触摸显示屏的 RFID 读取器

如何设计一款基于 ESP32 且具有 ILI9341 触摸屏显示屏且适合壁挂式安装的美观 RFID 读取器。 本项目中用到的东西 硬件组件 ESP32 开发套件 C 1 AZ-Touch ESP 套件 1 RFID-RC522 IC卡读写器 1 ​编辑 电线、绕包线 1 详细设计流程 …

结构体实现位段

一.什么是位段 位段的声明和结构是类似的&#xff0c;有两个不同&#xff1a; 位段的成员必须是 int、unsigned int 或 signed int &#xff0c;在C99中位段成员的类型也可以 选择其他类型。 位段的成员名后边有⼀个冒号和⼀个数字 struct A {int a : 5;int b : 4;int c : 2…

SpringBoot的配置加载优先级

目录 一、背景分析 二、学习资源 三、具体使用 四、一些小技巧 方式一 方式二 一、背景分析 SpringBoot项目在打包之后&#xff0c;其配置文件就在jar包内&#xff0c;如果没有<配置文件优先级>这个机制&#xff0c;那么项目打成jar包之后&#xff0c;如果启动项目…